Разработка высоконагруженной системы на Node.js, Cassandra и Redis

Однажды заказчик поставил перед нами непростую, но интересную задачу: реализовать высоконагруженную систему, способную обрабатывать огромные массивы данных, передаваемых датчиками нефтяных вышек в реальном времени. Число датчиков могло варьироваться от 1 000 до 1 000 000, а каждый из них может отправлять данные с периодичностью от 1 до 60 секунд. Система также должна была отвечать следующим основным требованиям:

  • Высокая безопасность хранения данных;
  • Огромная пропускная способность;
  • Все технологии для критических частей системы должны быть свободным ПО.

Архитектура

Архитектура представлена на диаграмме, приведенной ниже. Давайте рассмотрим основные компоненты системы:

    Local agent. Локальный агент — это .NET приложение, реализованное в виде Windows-сервиса. Оно подключается к различным источникам данных и получает от них информацию. В качестве источников данных могут выступать OPC-серверы, веб-сервисы, базы данных, реализующие программный интерфейс ODBC, Web API сервисы, CSV-файлы. Локальный агент имеет свой уникальный номер и может быть сконфигурирован из веб-части системы или из файла конфигурации. Выбор способа конфигурации зависит от наличия Интернет-соединения.
  • Cassandra cluster. Cassandra – это открытая NoSQL СУБД, реализованная на языке Java сообществом Apache Software Foundation. Она отлично подходит для работы с большими объемами данных и предоставляет децентрализованное, масштабируемое, устойчивое хранилище.  У Cassandra есть собственный язык запросов – CQL (Cassandra Query Language). Также она поддерживает технологию MapReduce.
  • Web part. Состоит из двух основных частей. Первая часть – это веб-сайт с админкой и пользовательским интерфейсом. Администратор может управлять локальными агентами и их настройками, создавать пользователей и управлять их правами, редактировать формат отображаемых данных. Пользователь может авторизоваться на сайте и просматривать данные двух видов – архивные и в режиме реального времени. Для графиков мы использовали библиотеку Highcharts, для остального интерфейса – Bootstrap и Ext.js. Это позволило за минимальные сроки создать работающий и прилично выглядящий интерфейс. Вся бизнес-логика была реализована на Node.js. Вторая часть – это приложение «Cache Manager», реализованное на языке Java. Оно предназначено для обновления и очистки кэша данных. В качестве кэша мы использовали Redis.
Архитектура системы

Детали реализации

Одна из особенностей Cassandra – кластеризация. Мы собрали кластер из четырех машин. Настройка Cassandra и ее окружения заслуживает отдельной статьи. После настройки и генерации токенов для каждого узла кластера, мы получили следующую диаграмму в OpsCenter (система для визуального управления и мониторинга СУБД Cassandra):

Кластеризация в Cassandra

Круги — это узлы Cassandra. Зеленый цвет показывает, что все они функционируют в нормальном режиме. Равномерное расположение кругов относительно друг друга означает, что кластер сбалансирован.

Мы реализовали веб-часть с помощью Node.js и фреймворка Express.js, который позволяет на лету создавать Web API, а значит, можно отделить бизнес-логику от интерфейса. Все данные пользователей и их настройки хранятся в развернутой на том же сервере MySQL. За логику доступа к данным целиком и полностью отвечает модуль Node ORM2. Это очень удобная ORM, которая поддерживает много реляционных и NoSQL СУБД.

Чтобы избежать задержек при отображении данных в реальном времени на стороне клиента, мы создали кэш на движке Redis. В Redis лежат последние N записей, полученных от локальных агентов. Это было сделано, в частности, потому, что Cassandra может хранить миллионы и миллионы записей, а также имеет известные проблемы с фильтрацией данных. Таким образом, теперь мы не обращаемся каждый раз к Cassandra, а читаем свежие данные из кэша. На клиентской стороне есть несколько линейных графиков и таблиц с данными, содержимое которых обновляется каждую секунду.

Для анализа архивных данных и работы с ними, мы развернули Apache Hadoop. Hadoop – это фреймворк, который отлично справляется с обработкой больших объемов данных. Мы использовали Hadoop MapReduce.

Заключение

Зачем все это нужно? Сегодня мы каждый день встречаемся с постоянно растущим количеством данных, затрагивающих такие аспекты нашей жизни, как: наука, безопасность, социальные сети, торговля на бирже. Так как Cassandra легко масштабируется и позволяет хранить данные в любом виде, мы можем приспособить ее к хранению абсолютно любых бизнес-моделей в реальном времени и гарантировать безопасность, целостность, устойчивость и доступность информации в любое время. Кроме того, все эти инструменты являются свободным ПО — а значит, есть быстрый и удобный способ создания высоконагруженных систем.