Черги й стрімінг
Apache Kafka
Kafka це розподілений журнал подій для потокової передачі даних із високою пропускною здатністю та тривалим зберіганням.
Що це
Kafka створили в LinkedIn, відкрили у 2011 році, а згодом він став проєктом Apache. Це не класична черга, а розподілений журнал: повідомлення дописуються в кінець топіка та зберігаються задану кількість днів чи розміру, навіть після прочитання.
Топік ділиться на партиції. Порядок гарантується в межах партиції, а споживачі в одній consumer group ділять партиції між собою й можуть паралельно масштабуватися. Кожен споживач сам тримає свою позицію (offset) і може перечитати історію.
Kafka використовують для потоків подій, збору логів і метрик, CDC з баз даних, інтеграції мікросервісів та event sourcing. Нові кластери працюють в режимі KRaft без ZooKeeper.
Коли брати
- Потрібна велика пропускна здатність: сотні тисяч повідомлень за секунду.
- Події треба зберігати й перечитувати кількома незалежними споживачами.
- Будуєте потокову обробку, CDC чи event sourcing.
- Потрібен строгий порядок подій у межах ключа.
Коли не варто
- Потрібна проста черга задач для кількох воркерів: RabbitMQ чи SQS простіші.
- Обсяг малий, а команда не готова експлуатувати кластер.
- Потрібна маршрутизація повідомлень за складними правилами чи пріоритети.
Ключові поняття
- Topic / partition
- Топік це категорія подій, партиція це впорядкований шматок топіка для паралелізму.
- Offset
- Порядковий номер повідомлення в партиції, за ним споживач знає, де зупинився.
- Consumer group
- Група споживачів ділить партиції топіка: кожна партиція йде одному члену групи.
- Replication factor
- Скільки копій кожної партиції зберігається на різних брокерах.
- Retention / log compaction
- Політика зберігання: за часом, розміром або лише останнє значення для кожного ключа.
Приклад
Шпаргалка
| Команда або код | Що робить |
|---|---|
kafka-topics.sh --create --topic orders --partitions 3 --bootstrap-server localhost:9092 | Створити topic із 3 partition |
kafka-topics.sh --list --bootstrap-server localhost:9092 | Список topic |
kafka-topics.sh --describe --topic orders --bootstrap-server localhost:9092 | Деталі topic: partition і репліки |
kafka-console-producer.sh --topic orders --bootstrap-server localhost:9092 | Відправити повідомлення з консолі |
kafka-console-consumer.sh --topic orders --from-beginning --bootstrap-server localhost:9092 | Прочитати topic з початку |
kafka-console-consumer.sh --topic orders --group billing --bootstrap-server localhost:9092 | Читати як учасник consumer group |
kafka-consumer-groups.sh --describe --group billing --bootstrap-server localhost:9092 | Відставання (lag) групи по partition |
kafka-consumer-groups.sh --group billing --topic orders --reset-offsets --to-earliest --execute --bootstrap-server localhost:9092 | Скинути offset групи на початок |
kafka-topics.sh --delete --topic orders --bootstrap-server localhost:9092 | Видалити topic |
Як вивчити
- Зрозумій модель: topic, partition, offset, producer, consumer і consumer group, а також чим це відрізняється від черги.
- Запусти Kafka локально (режим KRaft, без ZooKeeper) у Docker і користуйся CLI скриптами.
- Створи topic, відправ повідомлення з консольного producer і прочитай їх consumer.
- Напиши producer і consumer на своїй мові (kafkajs, confluent, Java client) і побач, як працюють offset.
- Розберись із ключами повідомлень, порядком у межах partition і розподілом partition між консʼюмерами групи.
- Вивчи гарантії доставки: acks, ідемпотентний producer, at least once, exactly once, коміт offset.
- Додай обробку помилок, повторні спроби, dead letter topic та моніторинг відставання (lag).
- Прочитай про Kafka Connect, Schema Registry і Streams для інтеграцій та потокової обробки.
Питання на співбесіді
1. Чим Kafka відрізняється від звичайної черги?
У черзі повідомлення зникає після споживання. У Kafka воно лишається в журналі за політикою retention, і кілька споживачів читають його незалежно, зі своїми offset.
2. Як Kafka гарантує порядок?
Порядок гарантований лише в межах однієї партиції. Щоб події одного обʼєкта йшли по порядку, їх пишуть з однаковим ключем, тоді вони потрапляють в одну партицію.
3. Що таке delivery semantics?
At-most-once може втратити повідомлення, at-least-once може дублювати, exactly-once досягається ідемпотентним продюсером і транзакціями. На практиці роблять споживачів ідемпотентними.
4. Скільки споживачів може читати партицію?
У межах однієї consumer group лише один. Тому кількість партицій обмежує паралелізм групи. Інша група читає ті самі дані окремо.
Питання з банку співбесід
- Consumer RabbitMQ постійно перезапускається, CPU 100%, черга не рухається, хоча більшість повідомлень нормальні. В коді при будь-якій помилці робиться channel.nack(msg, false, true). Що це таке і як це лікувати? А як схожа ситуація виглядає в Kafka?MiddleSystem design
- Події замовлення
created,paid,shippedідуть через SQS standard. Поки consumer був один, усе працювало; після масштабування до чотирьох зʼявились замовлення, деpaidоброблено раніше заcreated, і обробник падає. Чому і як отримати порядок у межах одного замовлення без глобального порядку?MiddleSystem design - Топік має 6 партицій, lag росте. Команда збільшила deployment consumer з 6 до 12 подів, але lag не зменшився, а половина подів нічого не робить. Чому, що реально допоможе, і що буде, коли той самий топік почне читати ще один сервіс?MiddleSystem design
- Треба обрати брокер для двох потоків: задачі на генерацію мініатюр і події замовлень, які читають пʼять сервісів, причому новий сервіс аналітики хоче перечитати останні 30 днів. Для кожного потоку RabbitMQ чи SQS, чи Kafka, і чому?MiddleSystem design
- У піку 150 000 подій за секунду ClickHouse встигає приймати лише 100 000, consumer lag у Kafka росте на мільйони, а один ingest інстанс тим часом падає з OOM, бо producer буферизує в памʼяті. Опиши backpressure від сховища до клієнта: що робить кожен шар і що свідомо відкидаєш.SeniorSystem design
- Сервіс orders тримає копію назви і ціни товару, яку отримує з події ProductUpdated від catalog через Kafka. Після інциденту частина карток показує стару ціну, хоча в catalog нова. Логи consumer чисті. Назви три причини, як таке буває, і як побудувати копію, щоб вона сходилась сама.SeniorSystem design
- Вендор обіцяє "exactly-once delivery". Що ти запитаєш? Що насправді дають Kafka transactions? Чому це не вирішує проблему подвійного списання в Stripe?SeniorSystem design
- Топік: replication.factor=3, min.insync.replicas=1, producer з acks=1. Після падіння брокера зникли повідомлення, на які producer отримав успіх. Як саме це сталось? Яку конфігурацію ти поставиш і що вона коштує, коли падають один і два брокери?SeniorSystem design
Порівняння з цією технологією
Схожі технології
- RabbitMQRabbitMQ це зрілий брокер повідомлень із гнучкою маршрутизацією через exchanges, підтвердженнями та підтримкою AMQP.
- Apache PulsarPulsar це розподілена платформа обміну повідомленнями та стрімінгу з розділенням брокерів і сховища та вбудованою мультиорендністю.
- NATSNATS це легка та дуже швидка система обміну повідомленнями на Go з pub/sub, request-reply і стійким шаром JetStream.
- Redis StreamsRedis Streams це структура даних Redis у вигляді журналу подій із consumer groups, яку можна використати як легку чергу.
- Amazon SQSAmazon SQS це повністю керована черга повідомлень від AWS, яка масштабується автоматично й не потребує серверів.
Логотипи належать їхнім власникам і використані лише для ідентифікації. Іконки: Simple Icons (CC0), Devicon (MIT).