Все уроки
АрхитектураПродвинутый14 мин чтенияПолезно знать

Событийные системы: Kafka, RabbitMQ и очереди

События и команды, брокеры, партиции и consumer group'ы Kafka и как выбрать правильный инструмент.

  • Kafka
  • RabbitMQ
  • Topics & partitions
  • Consumer groups
Шаг 1/4
Producer'ы публикуют события — «заказ создан» — в topic. Kafka дописывает их в лог, по порядку.

За 30 секунд

В событийной системе сервисы объявляют факты («заказ оформлен»), а другие сервисы на них реагируют, вместо того чтобы вызывать друг друга напрямую. Брокер сообщений хранит и доставляет эти сообщения. Kafka — надёжный лог с возможностью повторного чтения, созданный для потоков с высокой пропускной способностью; RabbitMQ — гибкий маршрутизатор сообщений; очереди на Redis вроде BullMQ — простой вариант для фоновых задач. Правильный выбор зависит от требований к порядку, повторному чтению, пропускной способности и от того, сколько инфраструктуры вы готовы обслуживать.

Не в моём ежедневном стеке — я понимаю принципы и изучу детали, когда это понадобится проекту.

Почему это важно

  • События отвязывают producer'ов от consumer'ов: оформлению заказа не нужно знать, что на заказ реагируют и лояльность, и аналитика, и рассылка писем.
  • Брокер поглощает всплески трафика и сохраняет работу, когда consumer недоступен, — это делает системы гораздо устойчивее.
  • Kafka важна, когда команде нужны потоки с высокой пропускной способностью, долгое хранение и повторное чтение: аналитические пайплайны, журналы аудита, change data capture, много независимых потребителей одних и тех же данных.
  • Знание гарантий доставки каждого инструмента предотвращает классические баги: потерянные сообщения, дубликаты и обработку не по порядку.

Как это работает

01События, команды и брокеры

Команда просит кого-то что-то сделать: «отправь это письмо», «спиши деньги с этой карты». У неё один предполагаемый обработчик, и её можно отклонить. Событие сообщает факт, который уже произошёл: «заказ 42 оплачен». Ему всё равно, кто слушает: отреагировать могут ноль или десять потребителей. Если их путать, начинаются проблемы: «событие» с именем SendEmail привязывает producer'а к одному потребителю. Брокер сообщений — почта между ними. Producer'ы публикуют в него сообщения, он надёжно их хранит, а consumer'ы получают их в своём темпе. Если consumer лежит, сообщения ждут. Если трафик подскочил, растёт хвост очереди, а не плавится база. Цена — асинхронность: producer больше не знает, когда и выполнена ли работа вообще, поэтому нужен мониторинг хвостов и сбоев.

  • Команда: повелительное наклонение, один обработчик, может провалиться («ReserveStock»).
  • Событие: прошедшее время, много обработчиков, неизменяемый факт («StockReserved»).
  • Брокер: надёжный буфер и маршрутизатор между producer'ами и consumer'ами.

02Kafka: topic'и, партиции, offset'ы и consumer group'ы

Kafka — распределённый лог, в который можно только дописывать. Сообщения пишутся в topic, разбитый на партиции; каждая партиция — упорядоченная последовательность, где каждое сообщение получает offset (свой порядковый номер). Сообщения с одинаковым ключом всегда попадают в одну и ту же партицию, поэтому порядок гарантирован в пределах ключа (например, ID заказа), но никогда — по всему topic'у. Consumer'ы объединяются в consumer group; Kafka назначает каждую партицию ровно одному consumer'у в группе, так что число партиций ограничивает параллелизм. Каждая группа отслеживает свои закоммиченные offset'ы, а значит, много групп (биллинг, аналитика, поиск) читают один topic независимо. Сообщения не удаляются при чтении: они хранятся определённое время или до определённого объёма либо компактируются до последнего значения по каждому ключу. Начиная с Kafka 4.0 кластеры работают на KRaft без ZooKeeper, а в Kafka 4.2 появились готовые к продакшену share group'ы для потребления в стиле очереди.

bash
# Create a topic: 6 partitions, 3 replicas, 7-day retention
kafka-topics.sh --bootstrap-server localhost:9092 --create \
  --topic orders.v1 --partitions 6 --replication-factor 3 \
  --config retention.ms=604800000 --config min.insync.replicas=2
 
# Produce keyed messages (same key -> same partition -> ordered)
kafka-console-producer.sh --bootstrap-server localhost:9092 \
  --topic orders.v1 --property parse.key=true --property key.separator=:
 
# Inspect a consumer group: current offset, end offset and lag per partition
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --describe --group billing-service

03RabbitMQ и очереди на Redis

RabbitMQ — маршрутизатор сообщений. Producer'ы публикуют в exchange, который направляет сообщения в очереди через binding'и: direct (точный routing key), topic (шаблоны вроде «order.*»), fanout (во все привязанные очереди) или headers. Consumer'ы забирают сообщения из очередей и подтверждают их; неподтверждённые сообщения доставляются повторно, а отклонённые могут уйти в dead-letter exchange. После подтверждения сообщение исчезает, так что RabbitMQ — про доставку работы, а не про хранение истории (его stream-очереди добавляют режим, похожий на лог, когда нужно повторное чтение). Он хорош для маршрутизации отдельных сообщений, приоритетов и request-reply. Очереди на Redis, такие как BullMQ (Node) или очереди Laravel с драйвером Redis, — самый лёгкий вариант: задачи с повторами, backoff, задержками, rate limit'ами, задачи по расписанию и повторяющиеся задачи — всё на том Redis, который у вас, скорее всего, уже есть. Их ограничение — надёжность и масштаб: Redis держит данные в памяти, так что настройте persistence и относитесь к очереди как к исполнителю задач, а не как к постоянному хранилищу событий.

04Гарантии доставки на практике

Любой брокер предлагает какую-то комбинацию трёх гарантий. At-most-once: consumer коммитит до обработки, так что при падении сообщение теряется, но никогда не дублируется; приемлемо для метрик, редко — для бизнес-данных. At-least-once: consumer обрабатывает, затем подтверждает; падение между этими шагами означает повторную доставку, поэтому дубликаты случаются. Это реалистичный вариант по умолчанию для большинства систем. Exactly-once: каждое сообщение влияет на результат один раз. Kafka поддерживает это внутри Kafka — с помощью идемпотентных producer'ов и транзакций, когда consumer'ы читают только закоммиченные данные, — для пайплайнов read-process-write между topic'ами Kafka. Как только побочный эффект выходит за пределы Kafka (запись в базу, письмо, списание с карты), вы снова в мире at-least-once и должны сделать consumer идемпотентным: хранить ID обработанных сообщений, использовать уникальные ограничения или upsert'ы и проектировать обработчики так, чтобы их двойной запуск ничего не менял.

  • Сторона producer'а: acks=all и включённая идемпотентность (по умолчанию в современных клиентах Kafka).
  • Сторона consumer'а: коммитьте offset'ы после успешной обработки, а не до.
  • «Ядовитые» сообщения: повтор с backoff, затем перенос в dead-letter topic или очередь.

05Схемы, версионирование и выбор инструмента

События — это публичный контракт, который часто читают команды, с которыми вы никогда не встретитесь, поэтому относитесь к их структуре как к API. Описывайте схемы в Avro, Protobuf или JSON Schema, храните их в schema registry и применяйте правила совместимости: опциональные поля добавляйте свободно, но никогда не удаляйте и не меняйте назначение поля, на которое полагаются потребители. Для ломающих изменений публикуйте новый тип события или новую версию topic'а (orders.v2) и держите обе, пока потребители не переедут. Включайте в каждое сообщение ID события, тип, версию, таймстемп и ключ сущности. Как выбирать: Kafka — для больших потоков, долгого хранения, повторного чтения и множества consumer group'ов; RabbitMQ — для гибкой маршрутизации, распределения задач и подтверждения каждого сообщения; очереди на Redis вроде BullMQ — для фоновых задач приложения с повторами и расписанием; управляемые сервисы (SQS, SNS, Pub/Sub, managed Kafka) — когда вы не хотите сами обслуживать брокеры.

Когда применять

  • Многим независимым потребителям нужен один и тот же поток фактов (аналитика, индексация поиска, уведомления).
  • Нужно повторное чтение: перестроение read-модели, заполнение нового сервиса или аудит истории.
  • Высокая пропускная способность (от тысяч до миллионов сообщений в секунду) с порядком в пределах ключа.
  • Работа должна переживать простои consumer'ов и всплески трафика, не теряя запросов.

Когда не стоит

  • Одно приложение с фоновыми задачами: очередь на Redis или на базе данных проще и дешевле.
  • Вызывающей стороне нужен немедленный ответ: используйте синхронный API, а события оставьте для побочных эффектов.
  • Команда пока не умеет обслуживать и мониторить распределённый брокер: используйте управляемый сервис или очередь попроще.

Альтернативы

  • RabbitMQ

    Exchange'и и очереди с богатой маршрутизацией, подтверждениями и dead-lettering; идеален для распределения задач.

  • Redis + BullMQ / очереди Laravel

    Лёгкие задачи с повторами, задержками и rate limit'ами; не долгосрочный лог событий.

  • Управляемые облачные очереди

    SQS/SNS, Google Pub/Sub, Azure Service Bus: никаких брокеров на вашей стороне, оплата по использованию.

  • NATS / Redis Streams

    Лёгкий стриминг с consumer group'ами, когда Kafka слишком тяжела.

Лучшие практики

  1. Называйте события в прошедшем времени и держите их неизменяемыми фактами.
  2. Выбирайте ключи партиций по сущности, которой нужен порядок, и закладывайте число партиций с расчётом на будущих потребителей.
  3. Делайте каждый consumer идемпотентным; исходите из того, что любое сообщение может прийти дважды.
  4. Публикуйте события через transactional outbox, чтобы изменения в базе и сообщения никогда не расходились.
  5. Версионируйте схемы с помощью registry и проверок совместимости.
  6. Мониторьте consumer lag, dead-letter очереди и частоту повторов и алертите на их рост.

Частые ошибки

  • Ожидать глобального порядка в Kafka: он гарантирован только внутри партиции.
  • Коммитить offset'ы до обработки и терять сообщения при падении.
  • Использовать брокер как базу данных со спонтанными запросами вместо нормальных read-моделей.
  • Горячие партиции из-за перекошенного ключа (например, одного огромного клиента), которые ограничивают пропускную способность.
  • Менять структуру события без версионирования и тихо ломать потребителей.

Глубже

06Надёжность внутри Kafka: реплики, ISR и выбор лидера

У каждой партиции есть одна реплика-лидер, принимающая записи, и фолловеры, которые её копируют. In-sync replica set (ISR) — это лидер плюс фолловеры, отстающие не больше чем на replica.lag.time.max.ms. При acks=all продюсер получает успех, только когда запись есть у всех текущих членов ISR; min.insync.replicas задаёт, до какого размера может сжаться ISR, прежде чем записи начнут отклоняться с NotEnoughReplicas. Типичная надёжная конфигурация — replication factor 3, min.insync.replicas 2 и acks=all: один брокер может упасть без потери данных и без остановки записи. Оставьте unclean.leader.election.enable в значении по умолчанию false; если его включить, лидером может стать несинхронизированная реплика и молча потерять уже подтверждённые сообщения ради доступности. Распределяйте реплики по стойкам или зонам доступности через broker.rack, чтобы отказ одной зоны не унёс все копии.

  • RF 3 + min.insync.replicas 2 + acks=all: безопасно переживает потерю одного брокера.
  • Идемпотентность продюсера и acks=all — значения по умолчанию в клиенте начиная с Kafka 3.0.
  • Unclean election меняет подтверждённые данные на доступность; не включайте его.

07Ребалансировка, новый протокол консьюмеров и зависания обработки

Когда консьюмеры подключаются, уходят или падают, партиции перераспределяются в ходе ребалансировки. Классический протокол мог останавливать всю группу; cooperative-sticky assignment это смягчил, а протокол нового поколения (KIP-848), общедоступный начиная с Kafka 4.0, переносит назначение на group coordinator на стороне брокера и ребалансирует инкрементально. Клиенты включают его через group.protocol=consumer; группы переводятся во время rolling upgrade. Важны два таймаута. session.timeout.ms обнаруживает мёртвого консьюмера по heartbeat. max.poll.interval.ms обнаруживает зависшего: если обработчик между вызовами poll работает дольше, консьюмер исключается, его партиции переезжают, а незакоммиченный батч обрабатывается заново в другом месте. Поэтому медленные обработчики приводят к повторной работе и штормам ребалансировок. Уменьшите max.poll.records, вынесите долгую работу в отдельную очередь или ставьте партиции на паузу на время обработки.

08Компакция, retention и replay в больших масштабах

Retention может быть по времени или размеру (политика delete) или по ключу (политика compact). Компакция хранит как минимум последнюю запись для каждого ключа и в фоне удаляет более старые, превращая топик в надёжную таблицу текущего состояния: профили клиентов, цены товаров, конфигурацию. Запись с null-значением — это tombstone: она помечает ключ на удаление и сама удаляется через delete.retention.ms, поэтому консьюмеры, отставшие сильнее, могут пропустить удаления. Сочетание обеих политик хранит последнее значение по ключу и всё равно удаляет очень старые ключи. Replay — суперсила: новая consumer group, стартующая с самого раннего offset, восстанавливает read model из истории. Планируйте это: перестроение может читать терабайты, поэтому ограничивайте скорость, выделяйте ему собственную группу и убедитесь, что retention длиннее самого плохого реалистичного времени восстановления.

bash
# A compacted topic holding the latest price per product
kafka-topics.sh --bootstrap-server localhost:9092 --create \
  --topic prices.v1 --partitions 12 --replication-factor 3 \
  --config cleanup.policy=compact \
  --config min.compaction.lag.ms=3600000 \
  --config delete.retention.ms=86400000
 
# Rebuild a read model: new group, start from the beginning
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --group search-indexer-v2 --topic prices.v1 \
  --reset-offsets --to-earliest --execute

09Число партиций, перекос ключей и тюнинг пропускной способности

Партиции — единица параллелизма и порядка, поэтому выбирайте их число под параллелизм консьюмеров, который ожидаете через год-два, а не сегодня: добавление партиций позже перераспределяет ключи и ломает порядок по ключу на время изменения. Слишком много партиций тоже стоит дорого: больше открытых файлов, дольше выборы лидера и больше метаданных. Ключ с намного большим трафиком, чем у остальных, создаёт горячую партицию, которую один консьюмер вынужден обрабатывать в одиночку. Исправляйте перекос более мелким ключом (order ID вместо customer ID), если порядок важен только в пределах заказа, или «солите» известный горячий ключ на несколько подключей и сливайте результат дальше по потоку. Записи без ключа распределяются sticky partitioner, который заполняет один батч и только потом переходит к следующему. На продюсере linger.ms и batch.size меняют несколько миллисекунд latency на гораздо более высокую пропускную способность, а сжатие (lz4 или zstd) снижает нагрузку на сеть и диск.

Реальные ситуации

01

Consumer lag растёт каждый вечер

Проблема

Аналитическая consumer group в пик отстаёт на часы и догоняет только ночью. Добавление экземпляров консьюмеров не помогло.

Как решить

Запустите kafka-consumer-groups.sh --describe, чтобы увидеть lag по партициям. Если lag сосредоточен на одной-двух партициях, причина в перекосе ключей: смените ключ или «посолите» горячий. Если он распределён равномерно, а экземпляров уже столько же, сколько партиций, лишние экземпляры простаивают, поэтому увеличьте число партиций в новой версии топика и мигрируйте или ускорьте обработчик, батча записи в базу. Проверьте циклы ребалансировки из-за обработчиков, превышающих max.poll.interval.ms. Затем настройте алерты на скорость роста lag и time-to-drain, а не на абсолютное число.

02

Двойные списания после падения консьюмера

Проблема

Платёжный консьюмер иногда списывает с клиента деньги дважды. Логи показывают перезапуск консьюмера между списанием и коммитом offset.

Как решить

Это at-least-once доставка, работающая как задумано; обработчик просто не идемпотентен. Дайте каждому событию стабильный ID и передавайте платёжному провайдеру производный idempotency key, чтобы повторный вызов вернул исходный результат. Записывайте ID обработанных событий в той же транзакции базы, что и изменение локального состояния, с уникальным ограничением, и пропускайте уже виденные. Держите auto-commit выключенным и коммитьте offset только после обработки. Добавьте ежедневную задачу сверки локальных платежей с отчётом провайдера, чтобы поймать всё, что проскочило.

03

Выбор брокера для продукта среднего размера

Проблема

Команда поддерживает одно приложение, где уже есть Redis. Им нужны события заказов для email, loyalty и будущего аналитического пайплайна, и они спрашивают, внедрять ли Kafka прямо сейчас.

Как решить

Начните с сегодняшних потребностей: несколько консьюмеров, скромный объём, требования к replay пока нет. Очередь задач на Redis для побочных эффектов, которую питает transactional outbox, закрывает это без новой инфраструктуры. Проектируйте события так, будто они публичные (ID, версии, схемы), чтобы перенос в лог позже был изменением relay, а не переписыванием. Когда аналитике или нескольким независимым командам понадобятся история и replay, подключите managed Kafka и направьте на неё outbox relay, вместо того чтобы с первого дня самим держать брокеры.

Шпаргалка

Надёжный продюсер
acks=all, enable.idempotence=true (по умолчанию с 3.0)
Надёжный топик
--replication-factor 3 --config min.insync.replicas=2
Lag consumer group
kafka-consumer-groups.sh --bootstrap-server host:9092 --describe --group app
Replay с начала
kafka-consumer-groups.sh ... --group g --topic t --reset-offsets --to-earliest --execute
Протокол ребалансировки нового поколения (4.0+)
group.protocol=consumer
Читать только закоммиченные транзакционные данные
isolation.level=read_committed
Последнее значение по ключу
cleanup.policy=compact
Выше пропускная способность продюсера
linger.ms=10, batch.size=65536, compression.type=zstd
Чтобы обработчики не исключались
Уменьшите max.poll.records или увеличьте max.poll.interval.ms

Вопросы и ответы

Q1Kafka или RabbitMQ: как выбрать?

Я спрашиваю, для чего нужны сообщения. Если это поток фактов, который независимо потребляют несколько команд, нужны хранение и повторное чтение, а объём высокий — подходит Kafka: это надёжный лог с consumer group'ами и порядком в пределах ключа. Если это задачи, которые нужно распределять между воркерами, с правилами маршрутизации, приоритетами и подтверждением каждого сообщения, — лучше подходит RabbitMQ, и о нём проще рассуждать. Для фоновых задач внутри одного приложения часто хватает очереди на Redis вроде BullMQ. Важна и стоимость эксплуатации: управляемый вариант снимает с маленьких команд большую часть рисков.

Q2Как Kafka гарантирует порядок?

Только внутри партиции. Producer отправляет сообщения с ключом, по хэшу ключа выбирается партиция, и внутри неё сообщения сохраняют порядок и получают возрастающие offset'ы. Так что если ключом выбран ID заказа, все события одного заказа обрабатываются последовательно, а разные заказы — параллельно по разным партициям. Порядка между партициями нет. Порядок зависит и от producer'а: при включённой идемпотентности повторы не переставляют сообщения. Будьте осторожны при увеличении числа партиций: ключи могут попасть в новые партиции, и во время изменения порядок для «летящих» ключей может нарушиться.

Q3Что значит exactly-once в Kafka?

Kafka предлагает семантику exactly-once для потоков read-process-write, которые остаются внутри Kafka. Идемпотентные producer'ы не допускают дубликатов из-за повторов, а транзакции атомарно записывают выходные сообщения и offset'ы consumer'а, так что consumer, читающий с read_committed, видит каждый результат один раз. Для потоковой обработки это мощно. Но как только ваш обработчик пишет в базу, вызывает платёжный API или отправляет письмо, Kafka не может сделать этот внешний эффект exactly-once. На практике at-least-once доставку комбинируют с идемпотентными обработчиками — уникальными ключами, upsert'ами или таблицей обработанных сообщений, — чтобы получить exactly-once эффект.

Q4Что такое consumer lag и почему это важно?

Lag — разница между последним offset'ом в партиции и offset'ом, который закоммитила consumer group: сколько сообщений ждёт обработки. Это самый важный сигнал здоровья событийной системы. Растущий lag означает, что consumer'ы медленнее producer'ов — из-за бага, медленной зависимости, повторяющегося «ядовитого» сообщения или слишком малого числа consumer'ов. Поскольку одну партицию в группе читает один consumer, добавление consumer'ов сверх числа партиций не помогает. Я бы алертил на рост lag во времени, а не на фиксированное число, и смотрел бы его вместе с метриками dead-letter и доли ошибок.

Q5Как развивать схемы событий, не ломая потребителей?

Относитесь к событиям как к публичному API. Описывайте их в Avro, Protobuf или JSON Schema, регистрируйте в schema registry и включайте режим совместимости — обычно backward или full. Безопасные изменения — добавление опциональных полей со значениями по умолчанию; небезопасные — удаление, переименование или изменение смысла полей. Для ломающего изменения опубликуйте новую версию события или новый topic и держите обе, пока каждый потребитель не переедет, а затем выведите старую из оборота. Каждое сообщение должно нести свой тип и версию, чтобы потребители могли обрабатывать несколько версий во время перехода.

Q6Почему бы просто не использовать очередь на Redis для всего?

Для многих приложений — можно и нужно. BullMQ или очереди Laravel на Redis дают повторы, backoff, задержки, rate limit и расписание почти без дополнительной инфраструктуры. Ограничения появляются с ростом масштаба и потребностью в истории: Redis держит данные в памяти, persistence нужно аккуратно настраивать, задачи удаляются после выполнения, а встроенного повторного чтения для нового потребителя, которому нужны события за прошлый месяц, нет. Когда нескольким командам независимо нужен один и тот же поток или нужны долгое хранение и очень высокая пропускная способность, лог вроде Kafka становится лучшим инструментом. Выбирайте по потребности, а не по моде.

Вопросы уровня senior

S1Как гарантировать порядок по каждой сущности и при этом ретраить упавшие сообщения?

Порядок и ретраи конфликтуют: если сообщение 5 по заказу упало, а вы пошли дальше, сообщение 6 применится первым. Варианты по степени строгости. Блокировать партицию и ретраить на месте с backoff: порядок сохраняется, но одно «ядовитое» сообщение останавливает все ключи этой партиции, поэтому ограничьте число попыток и настройте алерт. Использовать retry-топик на каждый уровень задержки, но заодно «парковать» последующие сообщения того же ключа, пока упавшее не пройдёт, — для этого нужно небольшое per-key хранилище состояния. Или проектировать обработчики устойчивыми к беспорядку через версии: каждое событие несёт версию сущности, а консьюмер игнорирует всё, что старше сохранённого. Последний вариант лучше масштабируется и переживает replay, поэтому я предпочитаю делать изменения состояния проверяемыми по версии и идемпотентными, а строгую блокировку оставляю только для немногих потоков, которым она действительно нужна.

S2Своя Kafka или managed-сервис: что вы взвешиваете?

Хорошо эксплуатировать Kafka — значит планировать мощности брокеров и дисков, делать rolling upgrade, перераспределять партиции, настраивать rack-aware репликацию, мониторить under-replicated партиции и здоровье контроллера, плюс безопасность с TLS и ACL. Для этого нужны реальная экспертиза и время на on-call. Managed-сервис снимает большую часть этого, часто добавляет tiered storage и автоскейлинг, а платите вы более высоким счётом за единицу пропускной способности, некоторым lock-in по инструментам и меньшим контролем над версиями и тюнингом. Для команды без выделенных платформенных инженеров managed почти всегда дешевле, если учесть зарплаты. Self-hosting начинает иметь смысл при больших стабильных объёмах, строгих правилах размещения данных или когда платформенная команда уже эксплуатирует похожие stateful-системы. В любом случае держите клиентов на стандартных протоколах Kafka, чтобы переезд оставался возможным.

S3Event sourcing на Kafka: хорошая идея или нет?

Kafka отлично подходит для распространения событий, но как основное хранилище для event-sourced агрегатов она слаба. Event sourcing требует быстро загружать все события одной сущности и дописывать, только если сущность всё ещё в ожидаемой версии, — это проверка optimistic concurrency. В Kafka нет ни чтения по сущности, поскольку топики разбиты по ключу на множество сущностей, ни условного дописывания. Команды, которые пробуют это, в итоге строят отдельное хранилище снапшотов и борются с race condition. Лучший дизайн хранит event store в базе данных или специализированном event store с версионированием по потоку, а затем публикует эти события в Kafka через outbox или change data capture для других консьюмеров. Тогда Kafka делает то, в чём она хороша: fan-out, retention и replay для проекций.

Глоссарий

Партиция
Упорядоченная часть топика, в которую можно только дописывать; единица порядка и параллелизма.
Offset
Порядковый номер записи внутри партиции.
Consumer group
Набор консьюмеров, делящих партиции топика, со своими закоммиченными offset.
ISR
In-sync replicas: лидер и фолловеры, отстающие настолько мало, что учитываются для acks=all.
Ребалансировка
Перераспределение партиций между консьюмерами группы при изменении её состава.
Log compaction
Хранение как минимум последней записи по каждому ключу с удалением старых версий.
Tombstone
Запись с null-значением, помечающая ключ на удаление в компактированном топике.
KRaft
Встроенный кворум метаданных Kafka на базе Raft; единственный режим с тех пор, как Kafka 4.0 убрала ZooKeeper.
Dead-letter topic
Куда попадают сообщения после повторных ошибок обработки — для разбора и повторного проигрывания.

Есть идея продукта?Давайте создадим его.

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