Брокеры сообщений и Kafka
Kafka часто путают с обычной очередью задач, а это разные инструменты под разные задачи. Собес проверяет, понимаешь ли ты, что Kafka - устойчивый лог событий с перечитыванием, и знаешь про at-least-once и порядок в пределах партиции.
Типовые формулировки: «чем Kafka отличается от очереди задач?», «сколько раз доставится событие?», «гарантирует ли Kafka порядок».
Лог событий, а не раздача задач
Очередь задач раздаёт работу воркерам: сообщение исчезает после обработки - его забрал один воркер и сделал. Kafka устроена иначе: это устойчивый упорядоченный ЛОГ событий. Записи хранятся, потребитель читает по offset (своей позиции) и при необходимости может перечитать историю заново.
Отсюда разные модели. Одно событие в Kafka НЕЗАВИСИМО потребляют несколько групп это про потоки событий, а не про раздачу задачи одному исполнителю. Это pub/sub, fan-out: событие «заказ оформлен» получают и склад, и биллинг, и аналитика - каждая группа своим темпом. В очереди задач сообщение забрал бы один воркер, и всё.
// Мысленная граница: нужен один исполнитель на задачу - очередь; нужен поток событий для многих независимых потребителей с историей - Kafka.
- Kafka
- устойчивый лог событий, чтение по offset, перечитывание
- pub/sub
- fan-out: событие получают все подписчики
At-least-once и порядок в партиции
Kafka по умолчанию даёт at-least-once: если сбой случился после обработки, но до фиксации offset, событие придёт СНОВА - потребитель обязан быть идемпотентным, иначе получишь дубли эффектов. Ждать exactly-once по умолчанию нельзя (он достижим особыми настройками, но это не дефолт).
Порядок держится лишь В ПРЕДЕЛАХ ПАРТИЦИИ, не глобально по топику. Топик разбит на партиции это единица и параллелизма, и порядка. События с одним ключом уходят в одну партицию и читаются по порядку, а между партициями глобального порядка нет. Рассчитывать на строгий порядок всего топика - ошибка.
// Поэтому ключ партиционирования выбирают так, чтобы связанные события (по одному заказу, пользователю) попадали в одну партицию и сохраняли порядок.
- offset
- позиция чтения потребителя в логе
- партиция
- единица параллелизма и порядка в топике Kafka
Как отвечать: «Чем Kafka отличается от очереди задач?»
Моделью. Очередь задач, Celery или RQ, раздаёт работу: сообщение забирает один воркер и после обработки оно исчезает это про «сделать задачу один раз силами одного исполнителя». Kafka это устойчивый лог событий: записи хранятся, потребители читают по своему offset и могут перечитать историю, а одно и то же событие независимо потребляют несколько групп, каждая своим темпом. То есть Kafka про потоки событий и fan-out на много подписчиков - заказ оформлен, и его слышат склад, биллинг, аналитика. Плюс у Kafka at-least-once и порядок только внутри партиции, так что потребитель идемпотентен, а связанные события кладу в одну партицию по ключу. Нужен один исполнитель на задачу - беру очередь; нужен общий поток событий с историей - Kafka.
Разведены обе модели (раздача задачи против лога событий), названы хранение, offset, fan-out, at-least-once и партиционный порядок и дан критерий выбора - глубокое различение, а не «Kafka это очередь побыстрее».
На чём валят
- −Считать Kafka обычной очередью задач: это лог событий с хранением и перечитыванием по offset.
- −Ждать exactly-once по умолчанию: at-least-once даёт дубли - потребитель обязан быть идемпотентным.
- −Ждать глобального порядка событий: он гарантирован лишь внутри партиции, не по всему топику.
- −Раскидывать связанные события по партициям случайно - теряется их порядок; нужен ключ партиционирования.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Чем pub/sub (публикация-подписка) отличается от очереди с одним получателем?A)Очередь рассылает всем, а pub/sub отдаёт строго одному получателюB)В pub/sub сообщения вообще не сохраняются и не имеют получателяC)Pub/sub работает только внутри одного процесса приложения памятиD)В pub/sub одно событие получают все подписчики, а не один воркер
показать ответ и разбор
+D)В pub/sub одно событие получают все подписчики, а не один воркер// разбор: В очереди задач сообщение забирает один воркер (work queue) — работа делится. В pub/sub одно событие доставляется всем подписчикам независимо (fan-out): заказ оформлен → и склад, и биллинг, и аналитика узнают об этом каждый у себя. Kafka с группами потребителей совмещает обе модели.
- Kafka гарантирует at-least-once. Что это значит для потребителя?A)Событие может прийти повторно — обработчик должен быть идемпотентнымB)Событие может потеряться, поэтому важные данные шлют мимо KafkaC)Порядок событий не сохраняется даже внутри одной партицииD)Событие придёт строго один раз, о дубликатах можно не думать
показать ответ и разбор
+A)Событие может прийти повторно — обработчик должен быть идемпотентным// разбор: At-least-once: при сбое подтверждения offset событие будет доставлено снова, так что потребитель обязан переживать дубли — делать обработку идемпотентной (по ключу события/дедупликации). Порядок Kafka держит в пределах партиции. Точная семантика exactly-once достижима, но дороже и с оговорками.
- Чем Kafka принципиально отличается от очереди задач?A)Kafka удаляет сообщение сразу после прочтения, как только один потребитель его забралB)Ничем: Kafka — это обычная очередь задач, просто с другим названием и APIC)Это устойчивый упорядоченный лог событий: записи хранятся, их можно перечитатьD)Kafka выполняет сообщения сама, тогда как очередь задач лишь передаёт их воркерам
показать ответ и разбор
+C)Это устойчивый упорядоченный лог событий: записи хранятся, их можно перечитать// разбор: Очередь задач раздаёт работу воркерам, и сообщение исчезает после обработки. Kafka — устойчивый упорядоченный лог событий: записи сохраняются на заданный срок (retention), а потребитель читает их по offset и может перечитать с любой позиции. Это про потоки событий и их многократное независимое потребление, а не про раздачу задания одному воркеру.
- Почему Kafka выдерживает очень высокий поток записи событий?A)Держит все события только в оперативной памяти, вообще не обращаясь к диску при записиB)Пишет в лог последовательным дозаписыванием в конец — это дёшево для дискаC)Сжимает каждое событие перед записью, поэтому на диск попадает совсем мало данныхD)Выполняет события параллельно на многих ядрах, успевая за счёт этого принять больше
показать ответ и разбор
+B)Пишет в лог последовательным дозаписыванием в конец — это дёшево для диска// разбор: Kafka — append-only лог: события дозаписываются в конец файла партиции строго последовательно, а последовательная запись на диск на порядки дешевле случайной. Плюс батчинг записей и zero-copy при отдаче потребителям. Отсюда высокая пропускная способность и на запись, и на чтение. Данные при этом лежат на диске (по retention), а не только в памяти.
- Партиции топика Kafka — за что они отвечают?A)За глобальный порядок: Kafka держит единый порядок сообщений по всему топикуB)За параллелизм и порядок: порядок гарантирован внутри партиции, не глобальноC)За шифрование: каждая партиция шифрует свою часть сообщений отдельным ключомD)За резервное копирование: каждая партиция — это полная копия всего топика целиком
показать ответ и разбор
+B)За параллелизм и порядок: порядок гарантирован внутри партиции, не глобально// разбор: Топик делится на партиции — это единицы параллелизма: разные партиции читаются независимо разными потребителями группы, что масштабирует пропускную способность. Порядок сообщений гарантирован ТОЛЬКО внутри партиции, а не по всему топику. Поэтому сообщения, которым важен взаимный порядок (события одного заказа), направляют в одну партицию по ключу.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.