Проходить собеседование по IT не всегда просто, особенно когда речь идет о системах обработки данных в реальном времени. Kafka — ключевой инструмент для потоковой передачи событий, и работодатели часто проверяют, насколько кандидат понимает её механизмы и нюансы.
В этой статье мы разберём пять популярных вопросов о Kafka, которые могут встретиться на интервью: от основ чтения сообщений и работы с оффсетом до гарантии порядка обработки и выбора между Kafka и классическими очередями.
Вы узнаете, как профессионально и уверенно отвечать на такие вопросы, демонстрируя глубокое понимание работы Kafka и её применения в реальных проектах.
Чтение в Kafka организовано через консьюмеров — процессы, которые подключаются к брокерам и получают сообщения из топиков. Основной механизм построен на consumer-группах.
Consumer — процесс, который читает из Kafka
Когда консьюмер подключается, он указывает group.id — обязательный параметр. Консьюмеры с одинаковым group.id автоматически объединяются в одну группу. Kafka гарантирует, что каждая партиция топика будет обрабатываться только одним консьюмером внутри группы, что обеспечивает корректное распределение нагрузки.
При подключении consumer указывает параметр group.id
Например, у нас есть топик my-topic с тремя партициями и consumer-группа test1 с двумя консьюмерами. Kafka распределит партиции между консьюмерами: первый консьюмер получит первую партицию, второй — две оставшиеся.
Таким образом, каждый консьюмер читает только те партиции, которые ему назначены, обеспечивая параллельную и детерминированную обработку данных.
Что будет, если консьюмеров больше, чем партиций?
Если консьюмеров больше, чем партиций, часть консьюмеров будет простаивать. Например, при трех партициях и четырех консьюмерах четвертый консьюмер не получит данных.
Если consumer’ов будет больше, чем партиций, то лишние будут простаивать
Но Kafka динамически перераспределяет партиции: если один из работающих консьюмеров отключается, простаивающий консьюмер автоматически берет его партиции и продолжает обработку.
Сколько может быть консьюмер-групп?
Топик может обслуживать сколько угодно consumer-групп. Каждая группа получает полный поток сообщений, но внутри группы партиции делятся между консьюмерами.
У топика может быть сколько угодно consumer group, и каждая из них получит все сообщения из всех партиций топика
Это позволяет разным системам использовать один и тот же топик независимо: одна группа может заниматься аналитикой, другая — поиском аномалий, третья — отправкой уведомлений.
Вопрос №2
Что такое оффсет и зачем он нужен?
В Kafka каждое сообщение внутри партиции имеет порядковый номер — оффсет. Оффсет служит консьюмеру для отслеживания позиции чтения внутри партиции.
У каждого сообщения в партиции есть порядковый номер — оффсет
Например, представим топик с одной партицией (partition 0), в которой лежат четыре сообщения: A, B, C, D. Их оффсеты будут:
A → 0
B → 1
C → 2
D → 3
Consumer может закомитить оффсет — сохранить в Kafka, до какого оффсета он дочитал
Когда консьюмер из группы test читает топик, он может фиксировать свой прогресс. Если прочитаны сообщения A и B, консьюмер сообщает Kafka, что дошел до оффсета 1.
Kafka сохраняет эту информацию персистентно, так что позиция чтения группы надежно зафиксирована в кластере.
Что происходит при падении консьюмера?
Если консьюмер внезапно падает, новый консьюмер из той же группы при подключении запрашивает у Kafka текущий оффсет группы: «До какого оффсета мы уже дочитали?» Kafka отвечает: «До оффсета 1». Новый консьюмер начинает читать с оффсета 2.
Если consumer перезапустится, то начнет читать с закомиченного оффсета +1
Таким образом, Kafka обеспечивает устойчивость обработки и возможность продолжить чтение с того места, где остановились.
Можно ли в Kafka перечитать сообщения?
Еще одно ключевое преимущество Kafka — возможность повторного чтения сообщений. Пока данные хранятся в топике (не истек период retention), консьюмер может сдвинуть оффсет назад и перечитать сообщения.
Это особенно полезно, если в обработке произошла ошибка: можно исправить код и заново обработать данные.
Как сдвинуть оффсет?
Сдвинуть оффсет можно несколькими способами. Например, стандартная CLI-утилита kafka-consumer-groups позволяет указать:
брокера Kafka;
consumer-группу;
топик;
конкретную партицию и новый оффсет.
Чтобы перечитать сообщения в Kafka, нужно просто сдвинуть оффсет consumer’a в нужной партиции
После этого Kafka обновляет сохраненный оффсет, и консьюмер начинает чтение с указанной позиции.
Вопрос №3
Как гарантировать порядок обработки?
Прежде всего важно понимать, зачем нам нужен гарантированный порядок обработки.
Рассмотрим пример из банковской сферы. Допустим, у нас есть топик, в который поступают операции по счетам: клиент сначала пополняет счет на 500 рублей, а затем оплачивает покупку, например, бургер за 500 рублей. Обе операции записываются в Kafka как два отдельных сообщения.
В этом сценарии критически важно, чтобы события обрабатывались в том порядке, в котором они произошли: сначала пополнение, затем списание. Если сообщения попадут в разные партиции, Kafka не гарантирует порядок между партициями.
Если consumer вдруг обработает первым снятие денег со счета, то будет ошибка
Сообщения будут прочитаны консьюмерами в произвольном порядке. Если списание произойдет раньше пополнения, система попытается списать средства с пустого счета — это приведет к ошибке и недовольству клиента.
Именно поэтому для таких сценариев критически важна гарантия порядка.
Kafka обеспечивает строгий порядок внутри партиции благодаря двум свойствам:
внутри consumer-группы одну партицию читает только один консьюмер;
консьюмер читает сообщения последовательно по оффсетам.
Соответственно, если мы хотим гарантировать порядок обработки связанных событий, все эти события должны попасть в одну партицию. В нашем примере это означает, что все операции по конкретному банковскому счету должны записываться в одну и ту же партицию.
Все сообщения в одной партиции читаются в строгом порядке
Как сделать так, чтобы связанные сообщения попадали в одну партицию?
В писателях kafka есть настройка partitioner.class. Если разработчик не указывает ни партицию, ни кастомный partitioner, используется дефолтный алгоритм:
у каждого сообщения есть ключ (key) и значение (value)
из ключа вычисляется хэш
хэш делится на количество партиций
остаток от деления определяет номер партиции
Хэш вычисляет Kafka SDK внутри метода send(), разработчику вручную ничего делать не нужно.
Как Kafka определяет, в какую партицию попадет сообщение: вычислим хеш от сообщения «123» (например, это номер счета), возьмем остаток от деления хеша ключа на количество партиций, записываем в нужную партицию
Почему это гарантирует порядок?
Если в нашем примере ключом сообщения является account_id, все операции по одному счету будут иметь одинаковый ключ. Соответственно, хэш ключа одинаков, и все сообщения с этим ключом попадут в одну и ту же партицию, если количество партиций неизменно. Консьюмер будет читать их строго последовательно, сохраняя порядок операций.
Что если ключ не нужен, а важна равномерная нагрузка?
Для таких задач, как сбор логов, телеметрия или аналитические потоки, порядок между событиями не критичен, а важна равномерная нагрузка на партиции.
В этом случае можно использовать:
round-robin: в настройках клиента partitioner.class = round-robin — сообщения последовательно распределяются между партициями, обеспечивая баланс нагрузки;
Указываем org.apache.kafka.clients.producer.RoundRobinPartitioner для распределения сообщений
кастомное партиционирование: можно реализовать собственный алгоритм распределения, учитывая бизнес-логику или свойства сообщений.
В коротком итоге, если нужно сохранить строгий порядок, используем один и тот же ключ для связанных сообщений — Kafka гарантирует последовательное чтение внутри одной партиции. Но если важна равномерная нагрузка, применяем round-robin или кастомный partitioner.
Kafka позволяет гибко балансировать между строгим порядком сообщений и масштабируемостью нагрузки в зависимости от требований конкретного кейса.
Вопрос №4
Когда удаляются данные в Kafka?
На первый взгляд кажется, что всё просто: по умолчанию сообщения удаляются через 7 дней, согласно настройке retention policy. Но на практике механизм немного сложнее. Kafka не отслеживает каждый отдельный message и не удаляет его по отдельности. Для понимания процесса важно разобраться с понятием сегмента.
Как сообщения хранятся в Kafka?
Физически Kafka сохраняет данные в сегмент-файлах на диске. Каждая партиция топика состоит из последовательности сегментов. Удаление сообщений привязано именно к удалению сегмента.
Внутри партиции сообщения разложены по сегментам
Сегмент закрывается в двух случаях:
когда достигает максимального размера segment. bytes (по умолчанию 1 ГБ);
когда прошёл заданный период жизни сегмента segment. ms (по умолчанию 7 дней).
После закрытия сегмента новые сообщения записываются в следующий сегмент.
Когда данные реально удаляются?
Ключевой момент: Kafka удаляет данные целыми сегментами. Сегмент удаляется, когда у последнего сообщения внутри него прошёл ретеншн-период.
После 7 дней сегмент закрывается и создается новый файл
Разберем пример: сегмент содержит 7 сообщений, по одному на день: 1, 2, 3, 4, 5, 6, 7, при retention.ms = 7 дней. Когда у первого сообщения пройдут 7 дней, сегмент не удаляется сразу. Удаление произойдет только после того, как ретеншн пройдет у последнего сообщения в сегменте.
Если у последнего сообщения не прошел retention (7 дней), то сегмент не удаляется
Если retention прошел у последнего сообщения в сегменте, то первый сегмент удаляется
Таким образом, сообщения могут храниться немного дольше, чем указанный период, пока сегмент целиком не станет «устаревшим».
Другие способы удаления сообщений
Удаление по времени — не единственный механизм. Kafka поддерживает политику компактификации (compaction):
сообщения с одинаковым ключом (key) сохраняются в топике до появления нового сообщения с тем же ключом
при появлении нового сообщения старые версии с тем же ключом постепенно удаляются
Такой топик называется compacted, и он идеально подходит для хранения текущего состояния объекта, например, баланса счета.
Kafka позволяет гибко управлять компактификацией через min.compaction.lag.ms — минимальное время хранения перед удалением старых сообщений по ключу. Например, можно оставить полную ретеншн-политику на год, а компактификацию по ключу делать раз в неделю.
Таким образом, в Kafka нельзя удалить отдельное сообщение по конкретному оффсету вручную. Данные удаляются либо целыми сегментами после истечения ретеншн-периода, либо постепенно по ключам при компактификации.
Вопрос №5
Когда использовать Kafka, а когда обычную очередь, например RabbitMQ?
Это действительно один из сложных вопросов, потому что однозначного ответа нет. Практически любую задачу можно реализовать и через Kafka-топик, и через очередь RabbitMQ, но особенности технологий влияют на удобство реализации и затраты усилий.
Основное отличие в том, что Kafka топики масштабируется горизонтально.
Топики можно распределять на разные брокеры, что позволяет выдерживать значительно большую нагрузку, чем обычная очередь. Поэтому Kafka — хороший выбор для сценариев с высокой нагрузкой, где стандартная очередь может не справиться.
Под какие задачи лучше подходят топики, а под какие — очереди?
1
Роутинг сообщений
Роутинг сообщений — это процесс распределения сообщений между потребителями таким образом, чтобы разные группы читателей получали разные типы данных.
Например, один потребитель может быть подписан на все события, связанные с банковскими операциями по всей стране, а другой — только на события, которые происходят в Москве.
В случае очередей это обычно реализуется достаточно просто: потребитель задает правило или шаблон, по которому он хочет получать сообщения. Например, в RabbitMQ можно указать шаблон вида card.create и использовать маску, например звездочку, чтобы получать сообщения из всех городов или только из Москвы.
Важный нюанс: такая фильтрация работает только в том случае, если отправитель сообщения заранее добавил соответствующий хедер в это сообщение в момент его публикации.
Например, если вы захотели фильтровать сообщения не по городам, а по странам, то сделать это уже не получится, если такого хедера просто нет. Аналогично, если вы хотите фильтровать сообщения по конкретному банковскому клиенту, это также невозможно без соответствующего хедера.
То есть в некоторых случаях это можно реализовать, но только если изначально с отправителем сообщения была согласована структура и набор этих метаданных.
В топиках Kafka подход другой. Там чаще всего приходится писать отдельное приложение, которое уже по заданной бизнес-логике распределяет сообщения по разным топикам. Это даёт больше гибкости, потому что вы можете использовать ESQL или любой другой язык программирования и самостоятельно описывать правила маршрутизации сообщений для разных потребителей.
2
Распределение задач по воркерам
В очередях RabbitMQ сообщения читаются по порядку: первый воркер берет первое сообщение, второй — второе и так далее.
В RabbitMQ в очереди сообщения распределяются равномерно между читателями
В Kafka консьюмер-группа делит партиции между воркерами, и каждый получает целую партицию.
В Kafka если добавится новый consumer, то он ничего не получит, пока мы не добавим партиций
Однако есть нюансы: если добавить нового консьюмера, он не начнет получать сообщения, пока не добавлены новые партиции. В очередях новый воркер сразу начинает читать сообщения.
Ещё один момент, который нужно учесть — это блокировки в Kafka: если одно сообщение не может быть обработано, последующие ждут.
В Kafka 4.1 появился queues over kafka, который позволяет параллельно читать сообщения из одной партиции разными консьюмерами
3
Обмен сообщениями между микросервисами
Оба инструмента подходят. Разница в том, что Kafka лучше масштабируется, а очереди проще настраиваются для фильтрации. Важно проводить нагрузочные тесты, чтобы убедиться, что выбранный инструмент выдержит вашу нагрузку.
4
Сбор логов приложений
Kafka часто используют для телеметрии и логирования: логи приложений отправляются через Kafka в промежуточное хранилище. Существуют готовые фреймворки: Logstash, Fluentd, Telemetry Frameworks.
Очереди для таких задач обычно не используют, потому что они хуже справляются с масштабированием и высокой нагрузкой. Kafka позволяет горизонтально масштабировать обработку от тысяч микросервисов одновременно.
5
Поставка данных в Data Platform
Kafka часто выступает промежуточным слоем для ETL: собирает данные с баз данных, приложений, мобильных устройств и передает их в аналитические хранилища.
Ingest — поставка в дата-платформу
Для Kafka существуют open source приложения, которые умеют собирать данные в нее из самых разных источников без написания кода
Kafka Connect — open-source фреймворк, который позволяет подключить источники данных и публиковать их в Kafka.
Они же умеют выгружать данные из Kafka в целевые системы без написания кода
Данные можно выгружать в Hadoop, ClickHouse, Greenplum и другие системы.
Очереди обычно для таких задач не применяются, так как не позволяют многократное чтение данных для разных целей.
Краткий итог по выбору между топиками и очередями:
роутинг сообщений проще реализовать на очередях, но Kafka даёт больше гибкости при кастомной логике;
распределение задач по воркерам: очереди работают «из коробки», а Kafka требует внимания к edge-кейсам, но новые функции в Kafka 4.1+ решают проблему;
обмен сообщениями между микросервисами: оба варианта подходят, но Kafka лучше масштабируется;
сбор логов и поставка данных в Data Platform: Kafka выигрывает благодаря горизонтальному масштабированию и готовым фреймворкам.
Таким образом, Kafka подходит, когда нужна высокая нагрузка, масштабирование и возможность многократного доступа к данным; а очередь (RabbitMQ) — когда важна простота, невысокая нагрузка и стандартные сценарии маршрутизации.
6. Заключение
Мы разобрали пять ключевых вопросов про Kafka: как читаются сообщения через consumer-группы, зачем нужен оффсет, как гарантировать порядок обработки, когда удаляются данные и когда выбирать Kafka вместо обычной очереди. Понимание этих основ дает вам полный контроль над потоками данных и архитектурой системы.
Даже если кажется, что вопросы сложные, не стоит бояться собеседования. Разобрав принципы работы Kafka, вы сможете объяснить всё на примерах и показать, что реально понимаете, как строится надёжная обработка событий.
1.5 месячный курс
Kafka для разработчиков: тонкости и нюансы
Глубокий курс про внутреннее устройство, лучшие практики, паттерны и антипаттерны — все для работы в highload-проектах. На примере реальных кейсов