Концепции хранения в Kafka

Основные компоненты Kafka

Концепция хранения в Kafka основана на следующих компонентах:

  • Сообщение (message) — запись произошедшего события, в том числе состояния обьекта, значения физической величины или любого другого параметра, который требует отслеживания, хранения или передачи в другую систему.

  • Производитель (producer) — клиентское приложение, публикующее (записывающее) сообщения в Kafka.

  • Потребитель (consumer) — клиентское приложение, которое подписывается (читает и обрабатывает) сообщения.

  • Топик (topic) — категория (тема), в которой сообщения публикуются в Kafka. В топике сообщения пишутся в журнал коммитов.

  • Журнал коммитов (commit log) – упорядоченная структура сообщений, доступная только для записи. В журнале коммитов нельзя ни изменять, ни удалять данные. Большие журналы разделяют на партиции. Если журнал состоит из одной партиции, то он и является партицией.

  • Партиция (partition) — упорядоченная неизменяемая последовательность записей, содержимое журнала коммитов.

  • Брокер (broker) — сервер, на котором хранятся партиции.

  • Сегмент (segment) — часть партиции, хранящаяся в отдельном файле на диске.

  • Группа потребителей (consumer group) — несколько потребителей, объединнных в группу для получения сообщений из одного или нескольких топиков. Партиции одного топика автоматически равномерно распределяются между потребителями в одной группе. Каждая партиция доступна только одному потребителю из группы.

Основные параметры при работе с Kafka

Производитель при записи сообщений указывает:

  • топик, в который будут записаны данные;

  • партицию, в которую будут записаны сообщения, имеющие одинаковый ключ (если это необходимо для структурирования данных в топике);

  • срок хранения сообщений в Kafka;

  • необходимое сжатие;

  • необходимый уровень подтверждения о записи сообщения в партицию и ее реплик;

  • коэффициент репликации партиций.

 
Потребитель для чтения сообщений указывает:

  • количество уникальных групп потребителей (consumer group);

  • group_id для каждой из групп потребителя, который определяет, откуда группа будет читать сообщения;

  • максимальное время ожидания клиентом ответа на запрос;

  • необходимый уровень подтверждения доставки сообщений (семантика).

 
Cообщение имеет следующие параметры:

  • данные (data);

  • ключ (key) для определения записи сообщений в одну и ту же партицию при необходимости (например, идентификатор клиента);

  • отметка времени (timestamp) и другие.

Последовательность записи и чтения сообщений

На рисунке ниже показана последовательность обработки сообщения внутри партиции при записи и чтении.

Запись и чтение сообщений в Kafka
Запись и чтение сообщений в Kafka
Запись и чтение сообщений в Kafka
Запись и чтение сообщений в Kafka
  1. Когда новое сообщение записывается в топик, оно фактически добавляется к одной из партиций топика.

  2. Каждому сообщению в партиции присваивается порядковый номер id, называемый смещением (offset), который однозначно идентифицирует каждую запись.

  3. Производитель получает подтверждение записи сообщения при помощи параметра конфигурации acks (acknowledgement), который указывает при каком условии запись считается записанной в партицию. Варианты значений параметра acks:

    • 0 — производитель считает записи успешно доставленными после их отправки на брокер;

    • 1 — производитель ждет от брокера-лидера подтверждение того, что он занес запись в лог;

    • all — производитель ждет подтверждения от брокера-лидера и реплик.

  4. Далее данное сообщение становится доступным для чтения потребителем.

  5. Экземпляр потребителя подключается со своим собственным group_id к топику. В соответствии с group_id ему назначается партиция для чтения и смещение в этой партиции, если они указаны. Если они не указаны, считывание начнется с сообщения, имеющего меньшее смещение из непрочитанных (самое раннее из записанных).

  6. Потребитель запрашивает сообщения из топика.

  7. Сообщения начинают последовательно считываться из журнала.

  8. При чтении из партиции потребитель делает коммит смещения (commit offset) - запись о считанном сообщении в служебный топик Kafka __consumer_offsets. Коммит смещения выполняется в соответствии с семантикой чтения сообщения, принятой в приложении потребителя. Варианты значений:

    • at most once — смещение принимается сразу после получения сообщения (если обработка не происходит, то сообщение теряется);

    • at least once — смещение принимается только после обработки сообщения (если обработка не происходит, то сообщение считывается повторно);

    • exactly once — все сообщения поставляются один раз.

  9. Cообщение со следующим по счету смещением cтановится доступно для чтения.

 

Метаданные каждого сообщения являются его смещением или положением в журнале. Смещение для начала чтения сообщения может быть установлено самим потребителем:

  • линейное продвижение смещения при считывании записи (по умолчанию);

  • считывание записи в любом порядке при необходимости (возвращение к более старому смещению или переход к самой последней актуальной записи).

Репликация и распределение партиций в брокере

Репликация

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

Коэффициент репликации (replication factor) — параметр, определяющий, сколько копий каждой партиции будет распределено на брокерах. Рекомендуемым значением коэффициента репликации (значение по умолчанию) является 3.

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

Брокеры разбивают каждую партицию на сегменты, каждый из которых хранится в отдельном файле данных на диске, подключенном к брокеру. По умолчанию каждый сегмент содержит либо 1 ГБ данных, либо данные за неделю, в зависимости от того, какой предел будет достигнут первым. При достижении лимита сегмента брокер закрывает файл и создает новый файл для записи новых сообщений. Активный сегмент — файл, в который в данный момент времени производится запись.

Синхронизация реплик

Формат репликации называется InSync. Это значит, что из всех реплик одна является лидером (leader), а другие последователями (followers). Производитель может управлять синхронностью/асинхронностью репликации при помощи параметра acks(acknowledgement).

Запись и чтение сообщений осуществляется через лидер-реплику партиции. Последователь, содержащий все сообщения, хранящиеся у лидера, называется синхронизированной репликой (in-sync replica, ISR).

Брокеры

Для обеспечения отказоустойчивости в кластере Kafka лидеры партиций автоматически распределяются по разным брокерам. Каждый брокер может быть лидером для одних партиций и последователем для других.

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

На рисунке ниже показано, как могут быть распределены партиции с заданной конфигурацией кластера:

  • количество брокеров — 3;

  • количество топиков — 2;

  • количество партиций в Topic 1 — 2;

  • количество партиций в Topic 2 — 1;

  • фактор репликации — 3.

Распределение партиций между брокерами Kafka
Распределение партиций между брокерами Kafka
Распределение партиций между брокерами Kafka
Распределение партиций между брокерами Kafka

Группы потребителей

Возможно создать большое количество конфигураций групп потребителей для чтения из топиков Kafka, но все они основаны на двух основных схемах обмена сообщениями — точка-точка (point-to-point) и публикация-подписка (publish-subscribe).

Группы потребителей управляются координатором группы потребителей.

Координатор группы потребителей — один из брокеров, который делает опрос всех потребителей группы потребителей. Если потребитель перестанет отправлять heartbeats, координатор инициирует ребалансировку потребителей.

Точка-точка

На рисунке ниже показано, как одна группа потребителей читает сообщения из одного топика.

Чтение сообщений со схемой
Чтение сообщений со схемой "точка-точка"
Чтение сообщений со схемой
Чтение сообщений со схемой "точка-точка"

Это вариант идеального распределения нагрузки.

У группы потребителей есть group_id, в котором есть информация, к какому топику подключаться и откуда начинать чтение. Kafka равномерно распределяет все партиции между потребителями одной группы.

Kafka дает доступ к партиции только одному потребителю (из группы потребителей) и каждый из них читает данные из одной партиции, имеющей одинаковый ключ (k1, k2, k3).

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

При отключении одного потребителя из группы его нагрузка (чтение из его партиции) перераспределится равномерно на других потребителей.

Публикация-подписка

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

Чтение сообщений со схемой
Чтение сообщений со схемой "публикация-подписка"
Чтение сообщений со схемой
Чтение сообщений со схемой "публикация-подписка"

Каждая группа потребителей при помощи параметров, указанных в ее group_id, может подписаться на любой топик или партицию с нужным ключом (k1, k2, k3).

При этом группы потребителей не зависят друг от друга.

Kafka действует как обычный топик издатель-подписчик (pub-sub), на который подписаны несколько потребителей, но Kafka при этом обладает преимуществом — все сообщения сохраняются и могут обрабатываться несколько раз.

Чаще всего топики имеют небольшое количество групп потребителей – по одной для каждого логического подписчика (logical subscriber).

При отключении одного потребителя из группы его нагрузка (чтение из его партиции) перераспределится равномерно на других потребителей (так же как и в схеме чтения точка-точка).

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней