Перфоманс Лаб

нагрузочное тестирование
тестирование
14 марта, 2025

Знакомимся с Apache Kafka.
Основы

Время чтения: 12 мин.
14 марта, 2025
Автор:
Иван Гроховатский
Apache Kafka — мощная распределённая платформа потоковой передачи данных, широко используемая для обмена сообщениями между приложениями. Инструмент обеспечивает быструю, надёжную и масштабируемую обработку больших объёмов данных в реальном времени.
Мы подготовили гайд для тех, кто только начинает знакомиться с Kafka и хочет понять, как она работает и чем отличается от традиционных систем обмена сообщениями.

Что такое Apache Kafka?

Apache Kafka —

это система, которая помогает приложениям обмениваться данным в реальном времени. Она способна собирать, хранить и передавать большие объёмы информации между программами. Kafka полезна, когда речь идет о быстрой обработке данных, например сообщения от клиентов.

Простыми словами: это группа серверов, которые работают вместе, чтобы обрабатывать непрерывный поток данных в реальном времени.

Kafka называют распредёленной потоковой платформой. Это означает, что инструмент работает не на одном компьютере, а одновременно на нескольких, объединенных в один кластер. Каждый узел (отдельный компьютер или, как принято называть, нода) в кластере называется Broker.

Простыми словами: брокеры — это серверы с запущенной Apache Kafka, а Kafka — это набор машин, работающих вместе, чтобы обрабатывать большой объем бесконечных данных в реальном времени.

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

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

Традиционный обмен сообщениями

Обмен сообщениями — это процесс передачи данных из одной программы в другую. В нем участвуют три основных элемента:

Производитель (Producer)

1/3
Программа, которая создает сообщения и отправляет их в одну или несколько очередей.

Очередь

2/3
Специальное место для хранения сообщений, где они держатся до тех пор, пока кто-то их не заберет. Очередь работает по принципу «первым пришел — первым ушел» (FIFO). Как только сообщение забрано, оно удаляется и восстановить его уже нельзя.

Потребитель (Consumer)

3/3
Программа, подписанная на одну или несколько очередей, которая получает сообщения сразу после их отправки.
Эта схема — классический пример системы обмена сообщениями, применяемой в большинстве MQ. Однако, когда речь идет о Kafka, всё немного иначе.

Архитектура Kafkа

Выше мы описали работу традиционного обмена сообщениями, теперь рассмотрим архитектуру Kafka, чтобы понять ее уникальность.
aрхитектура kafkа
В Kafka используются не очереди, а темы (далее топик).

Топик — это тип потока данных, напоминающий очередь: он также принимает и отправляет сообщения, но имеет несколько особенностей, таких как:
01

Разделы (или партиции) — это части топика, на которые он разбивается

Простой пример: представьте организацию папок. Топик — это как папка, а партиции — это папки внутри неё, в которых и хранятся данные.
02

Ключ сообщения

Используется для распределения сообщений по партициям. Сообщения с одинаковым ключом всегда попадают в одну и ту же партицию. Если же ключ не указан, то сообщения будут равномерно распределяться по всем партициям. Это значит, что порядок доставки сообщений внутри партиций не гарантируется.
В данном примере три сообщения отправляются в топик user-actions и попадут в одну партицию, потому что у них одинаковый ключ «PFLB».
пример работы с apache kafka
03

Каждое сообщение сохраняется на диске брокера и получает уникальный идентификатор — offset (смещение)

Offset — это уникальный идентификатор сообщения внутри конкретной партиции, который позволяет отслеживать его положение в потоке данных. Каждое новое сообщение добавляется в конец партиции и получает свой собственный offset.

К примеру:

  • Первое сообщение получит offset = 0
  • Второе сообщение получит offset = 1
  • Третье сообщение получит offset = 2
Это ещё одна уникальность Kafka. Инструмент сохраняет сообщения на диске как база данных, чтобы была возможность восстановить эти сообщения позже, если это необходимо. В обычной системе обмена сообщения удаляются сразу после использования.
04

Консьюмеры используют offset, чтобы отслеживать,  какие сообщения они уже прочитали и обработали

Во время чтения сообщения консьюмером Kafka запоминает его смещение, и если вдруг потребитель отключится во время сбоя,  позже он сможет продолжить чтение с последнего сохраненного offset`a, не пропустив данные.
чтения сообщения консьюмером kafka
Сообщения не удаляются сразу после того, как консьюмер их прочитает. Kafka сохраняет сообщения в течение определенного времени или до тех пор, пока общий размер данных в топике не превысит установленный лимит.

Удаление сообщений в Kafka управляется двумя основными параметрами:

01

Период хранения (retention period)

02

Лимит размера (retention size)

Структура Apache Kafka. Понятие кластера. Что такое Брокер?

Кафка Кластер (Kafka Cluster) —

это группа серверов (брокеров), которые работают совместно и обеспечивают надёжную и масштабируемую обработку и передачу данных. Объединяя несколько брокеров, кластер распределяет нагрузку, что обеспечивает отказоустойчивость системы.
Брокер (Broker) —

это сервер, который принимает и хранит данные, а также обрабатывает запросы от клиентов, например данные о заказах и платежах, поступающих от мобильного приложения и веб-сайта магазина. В кластере Kafka может быть один или несколько брокеров, что обеспечивает надёжность и масштабируемость системы. Если один брокер выйдет из строя, остальные продолжат работу, не теряя данных.
структура kafka

Слева изображена примерная схема Kafka Cluster.

ZooKeeper (Зукипер) —

это служба, которая следит за состоянием всего Kafka Кластера. Она отслеживает, какие брокеры активны и какую информацию они хранят. ZooKeeper можно сравнить с дирижером в оркестре: он координирует взаимодействие между компонентами, обеспечивая синхронизацию и согласованность данных. Перевод ZooKeeper с английского в прямом смысле означает «Смотритель зоопарка». Подразумевается, что он отслеживает все, что в нашем «зоопарке» происходит.
Основные функции ZooKeeper:
01

Хранение информации

Сохраняет данные о брокерах, топиках, разделах и потребителях, позволяя брокерам быть в курсе статуса друг друга и местонахождения нужных данных
02

Выбор лидера

Определяет «лидера» в каждой партиции, обеспечивая эффективное управление и обработку данных
03

Мониторинг состояния

Отслеживает состояние брокеров: если один из них выходит из строя, остальные брокеры сразу получают уведомление
04

Управление конфигурацией

Хранит параметры конфигурации, такие как настройки брокеров и топиков, позволяя изменять их без остановки всей системы

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

На схеме изображен топик «Топик 1» с тремя партициями,  распределенными между тремя брокерами: каждая партиция имеет основную копию (Leader) на одном из брокеров и две резервные копии (Followers) на других. Параметр Replication Factor в данном случае равен 3, то есть каждая партиция хранится на трех брокерах. Такой подход обеспечивает надёжность: при сбое одного из брокеров данные останутся доступными благодаря репликам на других брокерах.

структура kafka

Важно, чтобы количество партиций соответствовало количеству брокеров — так каждый брокер будет управлять одной партицией.

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

структура kafka

Далее определим лидера и фолловера партиции.

структура kafka

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

структура kafka

Consumer, Producer и их особенности

Продюсеры в Kafka —

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

По умолчанию сообщения распределяются по партициям топика с помощью метода round-robin, чтобы равномерно распределить нагрузку. Например, сообщение 01 может попасть в партицию 0, а сообщение 02 — в партицию 1. Это означает, что сообщения одного продюсера могут быть распределены по разным партициям, и порядок их доставки не гарантируется.

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

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

Что такое ACKS?

ACKS (acknowledgement) в Kafka — это информация о том, что сообщение было доставлено в брокер. ACKS является  настраиваемым параметром с тремя уровнями конфигурации:
01

Acks = 0

Устанавливается в том случае, если мы не хотим получать подтверждений от Kafka. В случае выхода брокера из строя, сообщение будет утеряно, но скорость работы будет быстрой.
02

Acks = 1

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

Acks = all

Эта конфигурация является самой надёжной. Она говорит о том, что мы хотим получать подтверждение не только от лидера (leader), но и от его реплик (followers). Таким образом, сообщение гарантированно будет находиться в партиции на брокере «лидере» и точно будет скопировано на другие машины, где расположены реплики (followers) этой партиции. Такая конфигурация самая безопасная, но также и самая медленная, поскольку Kafka будет ждать синхронизации всех реплик в ISR (группа реплик, синхронизированных с лидером, как показано на рисунке ниже).
acks в kafka
При настройке acks = all продюсеру отправляется подтверждение только после того, как все реплики в группе ISR (In-Sync Replicas) успешно синхронизировали данные.

ISR (In-Sync Replicas) — это группа реплик, синхронизированных с лидером. Давайте рассмотрим подробнее, как это работает:
01

Продюсер отправляет сообщение лидеру партиции

Когда продюсер отправляет сообщение в Kafka с настройкой acks = all, оно сначала записывается лидером партиции (то есть основной копией партиции, обрабатывающей операции записи и чтения).
02

Лидер передает данные фолловерам

После записи лидер партиции отправляет сообщение всем репликам (фолловерам) в ISR, чтобы они тоже синхронизировали данные.
03

Фолловеры подтверждают синхронизацию

Как только фолловеры записывают сообщение и данные становятся актуальными, они отправляют подтверждение (ack) лидеру, что они успешно синхронизировались.
04

Лидер отправляет финальное подтверждение продюсеру

Когда все фолловеры в ISR подтвердили синхронизацию данных, лидер отправляет финальное подтверждение продюсеру. Только после этого продюсер считает сообщение успешно доставленным.

Потребители и потребительские группы

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

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

Один потребитель — одна партиция

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

Один потребитель — несколько партиций

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

Потребители и потребительские группы

Для эффективной обработки больших объёмов данных Kafka использует концепцию потребительских групп. Группа потребителей позволяет распределить нагрузку между несколькими потребителями, обеспечивая масштабируемость и отказоустойчивость системы.

Принципы работы потребительских групп:
01

Распределение партиций

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

Масштабируемость

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

Отказоустойчивость

Если один из потребителей выходит из строя, Kafka перераспределяет его партиции между оставшимися потребителями, обеспечивая непрерывность обработки данных.
potrebiteli kafka

Параметр Retries

Retries —

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

Если продюсер не получил подтверждение в соответствии с настройками acks, он попытается отправить сообщение заново. Число повторных попыток ограничивается значением retries. Например, если retries = 3, продюсер попробует отправить сообщение до трех раз, если предыдущие попытки не удались. Это помогает компенсировать временные проблемы с сетью или перегрузку брокеров.
Важно:

Повторные отправки увеличивают нагрузку на сеть и могут привести к дублированию сообщений. Поэтому retries лучше всего использовать вместе с acks = all, чтобы гарантировать надёжность доставки и избежать дублирования данных.

Как правильно настроить acks и retries для минимизации потерь сообщений?

Для минимизации потерь сообщений рекомендуется использовать следующую комбинацию параметров:
01
Установите ack = all: как мы уже знаем, эта настройка обеспечивает надёжность, поскольку продюсер будет ждать подтверждений от всех реплик прежде, чем пометить сообщение доставленным.
02
Параметр retries следует устанавливать в разумных пределах. Оптимальное значение зависит от конкретной конфигурации вашего проекта, но для примера возьмём retries = 5. Это означает, что продюсер попытается отправить сообщение до пяти раз. Важно учитывать, что слишком высокое значение этого параметра может перегружать сеть.
03
Параметр max.in.flight.requests.per.connection ограничивает количество запросов, которые продюсер может отправлять одновременно. Если его значение равно 1, продюсер будет отправлять только одно сообщение за раз. Это снизит скорость работы, но повысит надёжность.
04
Параметр retry.backoff.ms определяет задержку между повторными попытками отправки сообщений. Например, если установить значение 100, продюсер будет ждать 100 миллисекунд перед повторной отправкой.
Для максимальной надёжности конфигурация может выглядеть так:
nastrojka acks i retries

Acks и retries —  лишь малая часть параметров, влияющих на надёжность Kafka. Разобрать их все в одной статье невозможно.

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

Семантика доставки сообщений в Apache Kafka

Kafka поддерживает три режима доставки сообщений:

At-most-once (не более одного раза)

1/3
Высокая производительность, возможна потеря данных, продюсер не ждёт подтверждения.

At-least-once (как минимум один раз)

2/3
Надёжный, но возможны дубликаты, продюсер повторно отправляет сообщение при сбое.

Exactly-once (ровно один раз)

3/3
Гарантированная доставка без потерь и дубликатов, но требует транзакций и ресурсов. Использование зависит от важности данных: для мониторинга, транзакций или критичных систем.
Транзакции —

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

Вывод

В данной статье мы разобрали ключевые аспекты работы с Apache Kafka:
01
Что такое Kafka и чем она отличается от традиционных систем обмена сообщениями
02
Основные элементы архитектуры: топики, партиции, ключи сообщений и оффсеты
03
Структуру кластера, включая брокеров и ZooKeeper, а также роль репликации в обеспечении надежности данных
04
Принципы работы продюсеров, потребителей и потребительских групп
05
Важные параметры надежности, такие как acks и retries, и их настройку для минимизации потерь данных
06
Семантику доставки сообщений (At-most-once, At-least-once и Exactly-once) и ее влияние на различные сценарии использования

Этот материал  — фундамент для работы с Apache Kafka. Понимание этих концепций поможет вам эффективно настраивать систему для обработки данных в реальном времени, обеспечивая ее надёжность и производительность. Однако это лишь отправная точка: чтобы глубже погрузиться в возможности инструмента, важно продолжать изучение и экспериментировать с настройками в реальных проектах.

Закажите нагрузочное тестирование у тех, кто умеет достигать поставленных целей

Увеличьте производительность вашей системы до максимума и застрахуйте свой бизнес.