Apache Druid

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 15:39, 27 мая 2019.
Apache Druid
Druid logo.png
Создатели: Eric Tschetter, Fangjin Yang
Разработчики: Apache Software Foundation
Постоянный выпуск: 0.14.1 / 9 May 2019 года; 4 months ago (2019-05-09)
Состояние разработки: Активное
Написана на: Java
Операционная система: UNIX-подобная операционная система
Платформа: Кроссплатформенная
Локализация: Английский
Тип ПО: distributed, real-time, колонно-ориентированное хранилище данных
Лицензия: Apache License 2.0 [Источник 1]
Веб-сайт druid.io

Apache Druid – это колоночная открытая база данных, написанная на Java. Druid спроектирован с целью быстрой обработки больших, редко изменяющихся массивов данных и немедленного предоставления доступа к ним.Он был разработан с целью обслуживания и поддержания 100% времени безотказной работы перед лицом развертывания кода, сбоев машин и других возможностей производственной системы. Это может быть полезно и для бэк-офисных случаев, но проектные решения были явно направлены на постоянную работу. Друид подходит для продуктов, которые требуют приема данных в реальном времени из одного большого потока данных. Особенно, если вы ориентируетесь на работу без простоя и создаете свой продукт поверх ориентированного на время суммирования входящего потока данных. Говоря о скорости запроса, важно уточнить, что означает «быстрый»: с друидом он полностью находится в пределах возможности для достижения запросов, которые выполняются менее чем через секунду через триллионы строк данных.

Особенности

  • Колоночное хранение данных
  • Мощная параллельная обработка данных
  • Возможность работы в режиме реального времени или в фоновом режиме
  • Облачная отказоустойчивая архитектура
  • Быстрая фильтрация
  • Точные и аппроксимированные вычисления

Архитектура

Полностью развернутый Druid работает как кластер специальных узлов, который гарантирует отказоустойчивость. [Источник 2] Данные хранятся в избытке и каждый узел дублируется несколько раз. Друид спроектирован как группировка систем, каждая из которых имеет определенную роль, и вместе они образуют рабочую систему (рисунок 1). Название происходит от класса Друид во многих ролевых играх: это изменчивость формы, способная принимать различные формы для выполнения различных ролей в группе.

Рисунок 1 - Архитектура

Разделение позволяет каждому узлу заботиться непосредственно о своих задачах. Отделяя обработку истории и реального времени, мы выделяем проблемы памяти при прослушивании потока данных в реальном времени и обработки его для входа в систему. Разделяя узлы-координаторы и узлы-брокеры, мы отделяем потребности в запросе от потребностей в поддержании «хорошего» распределения данных по кластеру.

Рисунок 2 показывает, как запросы и данные используют эту архитектуру, и какие узлы задействованы.

Рисунок 2 - Взаимодействие узлов при работе с данными

Все узлы могут быть запущены некоторым высокодоступным способом, либо как симметричные одноранговые узлы в кластере без общего доступа, либо как узлы переключения с возможностью «горячей» замены.

Помимо этих узлов существует 3 внешних зависимостей системы:

  1. Запущенный кластер ZooKeeper для обнаружения кластеров и обслуживания текущей топологии данных
  2. Экземпляр хранилища метаданных для обслуживания метаданных о сегментах данных, которые должны обслуживаться системой
  3. Хранилище / файловая система LOB с глубоким хранением для хранения сохраненных сегментов

Рисунок 3 иллюстрирует уровень управления кластером, показывающий, как определенные узлы и зависимости помогают управлять кластером путем отслеживания и обмена метаданными.

Рисунок 3 - Уровень управления кластером

Существующие типы узлов

Исторические узлы

Исторические узлы (Historical nodes) - это основные из видов узлов, которые обрабатывают хранение и запрос на «исторические» данные (не в реальном времени).[Источник 3] Исторические узлы загружают сегменты из глубокого хранилища, отвечают на запросы от брокер-узлов об этих сегментах и ​​возвращают результаты узлам брокера (рисунок 4).

Они объявляют себя и сегменты, которые они обслуживают в Zookeeper, а также используют Zookeeper для мониторинга сигналов для загрузки или отбрасывания новых сегментов.

Исторические узлы кэшируют некоторые сегменты на локальном диске, что позволяет им быстро обслуживать запросы в случае некоторого перезапуска. Обеспечивают согласованность чтения, поскольку имеют дело только с неизменяемыми сегментами.

Исторические узлы также могут быть разделены на несколько уровней, каждый из которых может быть настроен по-разному: одни могут быть размещены на уровне для обслуживания часто используемых данных, а другие - для остальных данных.

Наличие zookeepers ограничивает способность этих узлов загружать новые сегменты, но старые сегменты продолжают обслуживаться без каких-либо простоев.

Рисунок 4 - Работа исторических узлов

Узлы-координаторы

Узлы-координаторы (Coordinator nodes) контролируют группировку исторических узлов, чтобы обеспечить доступность данных, их репликацию и, как правило, «оптимальную» конфигурацию.[Источник 4] Они делают это, читая данные метаданных сегмента из хранилища метаданных, чтобы определить, какие сегменты должны быть загружены в кластер, используя Zookeeper для определения того, какие существуют исторические узлы, и создания записей Zookeeper, чтобы сообщить историческим узлам о загрузке и отбрасывании новых сегментов. Отключение Zookeeper препятствует возможности назначать или удалять новые сегменты, но старые сегменты по-прежнему могут быть запрошены.

Для контроля операцией выбирается один узел-координатор, остальные узлы действуют только как резервные.

Узлы-брокеры

Узлы-брокеры (Broker nodes) получают запросы от внешних клиентов и пересылают эти запросы в узлы реального времени и индексирования и исторические узлы (рисунок 5).[Источник 5] Когда брокер-узлы получают результаты, они объединяют эти результаты и возвращают их вызывающему. Для того, чтобы знать топологию, брокер-узлы используют Zookeeper для определения того, что существует в реальном времени и исторических узлах.

Эти узлы используют zookeeper для обнаружения других узлов. В случае сбоя zookeeper они обслуживают данные по последнему снимку состояния кластера.

Рисунок 5 - Узлы-брокеры

Узлы реального времени и индексирования

Узлы реального времени и индексирования (Middle Managers) отвечают за обработку данных в режиме реального времени (как чтение, так и запись).[Источник 6]

Запись состоит из 4 основных этапов:

  1. Запись - данные, записываемые в druid, сначала отправляются в буфер индексов этого узла. Этот буфер базируется на куче, а события хранятся по строкам (рисунок 6).
  2. Сохранение - для избежания переполнения кучи индекс периодически сохраняется на диск. Формат хранения данных теперь колоночный, а сами данные неизменны. Постоянный индекс загружается в память вне кучи для более быстрых запросов.
  3. Слияние - периодическая фоновая задача объединяет неизменяемые блоки в один сегмент.
  4. Передача - сегменты загружаются в распределенные хранилища данных
Рисунок 6 - Работа узла реального времени и индексирования (запись)

Управляющие узлы

Управляющие узлы (Overlord nodes) отвечают за принятие задач, координацию распределения задач, создание блокировок вокруг задач и возврат статусов вызывающим.[Источник 7] Overlord может быть настроен для работы в одном из двух режимов - локальном или удаленном (по умолчанию локальный).

Локальный режим обычно используется для простых рабочих процессов. В удаленном режиме процессы управляющих узлов и узлов реального времени и индексирования запускаются в отдельных процессах, поэтому их можно запускать на разных серверах.

Внешние зависимости

Глубокое хранилище

Для хранения всех данных, поступивших в систему, Druid использует общее хранилище файлов. Глубокое же хранилище используется только для резервных копий данных и для передачи данных в фоновом режиме (глубокое хранилище - место, где хранятся сегменты).[Источник 8]

Druid никогда не потребуется доступ к глубокому хранилищу во время запроса.

Хранилище метаданных

Хранилище метаданных содержит различные общие метаданные системы, такие как информация о доступности сегмента или информация о задаче. Обычно им является традиционная СУБД, такая как PostgreSQL или MySQL.[Источник 9]

Zookeeper

Apache Druid использует Apache ZooKeeper для управления текущим состоянием кластера.[Источник 10]

Операции, которые выполняются при помощи Zookeeper:

  1. Выбор главного узла-координатора
  2. Работа с сегментами протокола «публикации» исторических узлов и узлов реального времени и индексирования
  3. Работа с сегментами протокола загрузки / отбрасывания узлов-координаторов и исторических узлов
  4. Выбор главного управляющего узла
  5. Управление задачами управляющих узлов и узлов реального времени и индексирования

Получение и обработка данных

Сегменты и хранилище данных

Данные Apache Druid хранятся в «хранилищах данных», которые аналогичны таблицам в традиционных RDBMS (Relational Database Management System).[Источник 11] Каждое хранилище данных обязательно разделено по времени (может быть разделено дополнительно по другому атрибуту). Каждый временной диапазон называется «блоком» (например, если хранилище данных разделено по дням, блоком является один день). Внутри блока данные разделены на один или несколько «сегментов». Каждый сегмент представляет собой один файл, обычно содержащий до нескольких миллионов строк данных.

Пример устройства хранилища данных можно посмотреть на рисунке 7.

Рисунок 7 - Хранилище данных

Каждый сегмент начинает существование с момента его создания в узле реального времени и индексирования. В этот момент он (сегмент) является изменяемым.

Процесс создания сегмента включает в себя следующие этапы:

  1. Преобразование в столбчатый формат
  2. Индексирование с растровыми индексами
  3. Сжатие с использованием различных алгоритмов
    1. Сжатие с учетом типов для всех столбцов
    2. Кодирование словаря с минимизацией хранилища данных для столбцов String
    3. Сжатие растровых изображений для растровых индексов

Периодически сегменты записываются в глубокое хранилище, где становятся неизменяемыми. После этого с ними работают уже исторические узлы.

Информация о сегменте записывается в хранилище метаданных. Она включает в себя схему сегмента, его размер и его расположение в глубоком хранилище. Эти записи используются узлом-координатором, чтобы узнать, какие данные должны быть доступны в сегменте.

Таким образом, если исторический узел больше не может обслуживать свои сегменты, другой узел может просто загрузить сегмент и начать его обслуживать. Получается, можно удалить все исторические узлы, а затем заново запустить их без потери данных. Также, если глубокое хранилище недоступно, узлы могут продолжать обслуживать сегменты, с которыми они уже начали работать.

Идентификаторы сегментов

Каждый сегмент имеет идентификатор, состоящий из четырех частей:[Источник 12]

  1. Название хранилища данных
  2. Временной интервал
  3. Номер версии (необходим для перезаписи данных)
  4. Номер раздела (целое число, уникальное для каждого сегмента в наборе сегментов с одинаковыми частями идентификатора "хранилище данных - интервал - версия")

Состояния сегментов

Выделяют пять основных состояний, в которых может находиться сегмент: [Источник 13]

  1. Записанные, доступные, используемые - записанные в глубокое хранилище и в хранилище метаданных, данные сегменты обслуживаются историческими узлами и содержат в себе большую часть активной (то есть часто используемой) информации. Такие сегменты не содержат данные в реальном времени.
  2. Записанные, доступные, неиспользуемые - в отличие от предыдущего типа сегмента, данный тип обслуживается историческими узлами не постоянно. Это могут быть сегменты, которые были недавно перезаписаны или удалены.
  3. Записанные, недоступные, используемые - такие сегменты хранятся в глубоком хранилище и в хранилище метаданных и должны обслуживаться (так как содержат необходимую информацию), но фактически не обслуживаются. Если сегменты остаются в этом состоянии более нескольких минут, то обычно это означает, что что-то не так.
  4. Записанные, недоступные, неиспользуемые - сегменты хранятся в глубоком хранилище и в хранилище метаданных, но информация из них не используется.
  5. Незаписанные и доступные - сегменты в процессе создания. Включают в себя все данные в режиме реального времени.

Шестое состояние «незаписанный и недоступный» невозможно.

Создание сегментов и передача обслуживания

Индексирование (индексация) - это механизм, с помощью которого создаются новые сегменты.

Передача обслуживания - это механизм, с помощью которого новые сегменты записываются в глубокое хранилище и начинают обслуживаться историческими узлами.

Создание сегментов происходит следующим образом:[Источник 14]

  1. Механизм начинает работать и строить новый сегмент. Для создания сегмента необходимо для начала определить его идентификатор. Если идет добавление данных, произойдет вызов "allocate" API и будет добавлен новый раздел в существующий набор сегментов. Если же данные перезаписываются, блок с сегментами данного интервала времени блокируется и создается новая версия с новым набором сегментов.
  2. Если задача индексирования является задачей реального времени - немедленно создается новый сегмент в состоянии "незаписанный и доступный".
  3. Когда чтение данных для создания нового сегмента завершено, они (данные) помещаются в глубокое хранилище и в хранилище метаданных.
  4. Если задача индексирования является задачей в реальном времени, для загрузки сегмента необходим сигнал от исторического узла.

Передача обслуживания:

  1. Узел-координатор периодически обращается к хранилищу метаданных за информацией о новых сегментах (по умолчанию каждую 1 минуту).
  2. Если узел-координатор находит записанный, недоступный, используемый сегмент, он выбирает исторический узел и дает тому команду обслуживать этот сегмент.
  3. Исторический узел загружает сегмент и обслуживает его.
  4. Если задача индексирования в этот момент ожидало передачи обслуживания, то она завершается.

Методы получения данных

В таблице ниже представлены методы получения данных Apache Druid.[Источник 15]

Метод Как работает Возможность добавлять/перезаписывать Возможность работы в режиме реального времени
Native batch Druid загружает информацию напрямую из S3, HTTP, NFS или другого сетевого хранилища Добавлять и перезаписывать Нет
Hadoop Druid запускает Hadoop Map / Reduce для загрузки файлов данных Только перезаписывать Нет
Kafka indexing service Druid читает напрямую из Kafka Только добавлять Да
Tranquility Использование Tranquility - библиотеки на стороне клиента, чтобы помещать отдельные записи в Druid Только добавлять Да

Свертывание данных

Druid может объединять необработанные данные во время их получения, используя процесс свертывания.

Druid поддерживает два режима свертывания: [Источник 16]

  • Идеальное свертывание - гарантирует, что входные данные будут идеально агрегированы.
  • Максимальное свертывание - выдает меньший размер загруженных данных.

Действия с данными

Druid позволяет производить следующие действия с данными:[Источник 17]

  • Добавление и перезапись
  • Сжатие
  • Хранение и разделение на уровни (так называемые "горячий" и "холодный" уровни, отвечающие соответственно за новые и старые данные)
  • Удаление

Обработка запросов

Начинается все с того, что запрос переходит в узел-брокер, где последний определяет, какие сегменты имеют данные, относящиеся к этому запросу. Затем брокер идентифицирует, какие исторические узлы и узлы реального времени и индексирования обслуживают эти сегменты, и отправляет переписанный подзапрос каждому из них. Исторические узлы / узлы реального времени и индексирования будут принимать запросы, обрабатывать их и возвращать результаты брокеру, который объединит их вместе для получения окончательного ответа.

Druid использует три различных метода, чтобы максимизировать производительность запросов:

  1. Поиск по сегментам, доступным для каждого запроса (по времени или другим дополнительно определенным атрибутам).
  2. Определение нужных строк по индексам внутри каждого сегмента.
  3. Чтение определенных столбцов сегмента, которые имеют отношение к конкретному запросу.

Менеджмент кластера

Операции с данными в узлах истории находятся под контролям узлов координаторов, которые являются основными пользователями MySQL таблиц.

Туториал по установке Druid


Ссылки

Источники

  1. Apache License // Википедия. [2017—2017]. Дата обновления: 05.03.2017. URL: https://en.wikipedia.org/wiki/Apache_License (дата обращения: 05.03.2017).
  2. Architecture // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/index.html#architecture (дата обращения: 29.04.2019).
  3. Historical Process // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/historical.html (дата обращения: 29.04.2019).
  4. Coordinator Process // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/coordinator.html (дата обращения: 29.04.2019).
  5. Broker // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/broker.html (дата обращения: 29.04.2019).
  6. MiddleManager Process // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/middlemanager.html (дата обращения: 29.04.2019).
  7. Overlord Process // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/overlord.html (дата обращения: 29.04.2019).
  8. Deep Storage // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/dependencies/deep-storage.html (дата обращения: 29.04.2019).
  9. Metadata Storage // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/dependencies/metadata-storage.html (дата обращения: 29.04.2019).
  10. ZooKeeper // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/dependencies/zookeeper.html (дата обращения: 29.04.2019).
  11. Datasources and segments // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/design/index.html#datasources-and-segments (дата обращения: 29.04.2019).
  12. Segment identifiers // Overview // Ingestion // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/ingestion/index.html (дата обращения: 29.04.2019).
  13. Segment states // Overview // Ingestion // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/ingestion/index.html (дата обращения: 29.04.2019).
  14. Indexing and handoff // Overview // Ingestion // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/ingestion/index.html (дата обращения: 29.04.2019).
  15. Ingestion methods // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/ingestion/index.html (дата обращения: 29.04.2019).
  16. Roll-up modes // Rollup // Partitioning // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/ingestion/index.html (дата обращения: 29.04.2019).
  17. Data maintenance // Druid. [2011 - ]. Дата обновления: 29.04.2019. URL: http://druid.io/docs/latest/ingestion/index.html (дата обращения: 29.04.2019).