Изучаем Kafka — Уровень 1
- пятница, 13 июня 2025 г. в 00:00:12
Данная статья открывает серию из трёх материалов, каждый из которых представляет отдельный уровень изучения Kafka.
Если у тебя уже есть практический опыт работы с Kafka — первый уровень, скорее всего, не для тебя. Он предназначен для новичков, которые хотят понять, зачем вообще нужен Kafka и где он используется. На втором уровне ты углубишься в технологию — и этого уже будет достаточно, чтобы уверенно использовать Kafka в профессиональной работе. Третий уровень — это джедайский уровень. Не обязателен, но если ты его освоишь — будет круто. Серьёзно.
Прежде чем начать погружение в материал, давай поймём, какая картина мира была у авторов технологии Kafka. Вместо того чтобы читать 600 страниц мануала, где 70% — вода, 10% — ерунда и только 20% возможно суть, ты потратишь на это месяц или больше, а в итоге поймёшь, что надо бы всё перечитать ещё раз. Потому что без повторений в голове ничего не останется это факт, а заметки могут быть не полными, без визуальной картинки и практики ты просто потратишь время впустую, занимаясь самообманом будто что то запомнил. В самом конце статьи ты найдешь пример визуального представления, для полного погружения в технологию. Это будет финальным аккордом для закрепления первого уровня. Если ты уже знаком с терминологией можешь сразу спуститься до визуальной части, если пока нет то читай статью до конца. Удачи!
Удобная навигация по статье:
Topic / Partition / Offset — как Kafka всё это раскладывает по полочкам
Перемотка offset’а — как отмотать назад, если что-то пошло не так
Поток обработки (stream processing) — данные, которые не ждут
Если ты хоть раз писал код, который что-то логирует, или, не дай бог, строил микросервисную архитектуру — ты наверняка сталкивался с вопросом: а как, чёрт возьми, всё это между собой связать, чтобы не развалилось? Вот тут и появляется Kafka. Не как волшебная таблетка, а как такая штука, которую хочется поставить посередине и сказать: "всё, теперь все события у нас будут идти через тебя, ты как бы связующее звено между моими сервисами".
Короче, событие это просто факт. Ну типа:
чел залогинился
сделал заказ
добавил товар в корзину
термометр шлёт, что в серверной уже +90°С
Событие которые мы отправляем в Kafka это просто JSON (или Avro, или что угодно), но по сути:
{
"type": "user_logged_in",
"user_id": 456,
"timestamp": "2025-06-08T12:00:00Z"
}
Cобытия постоянно происходят, и Kafka это такой "пылесос", который их собирает, передаёт и позволяет другим частям системы реагировать на них мгновенно.
Представь обычную очередь как трубу: ты что то туда кидаешь, и оно вылетает на другом конце. Тот, кто поймал молодец. Всё. Больше никто не узнает, что там было.
А теперь представь Kafka как диктафон. Ты туда записал голос, и оно не исчезает, а хранится в памяти до определенного времени. Его можно:
прослушать сразу,
переслушать позже,
дать послушать другим.
Слушать с определенного времени на таймлайне
что делает Kafka?:
не удаляет сообщения сразу — хочешь, читай одни и те же события хоть 10 раз, хоть 100 раз
позволяет разным частям системы слушать одно и то же
хранит всё на диск, ничего не забывает
Кто слушает? Любые части твоего приложения. Их называют "слушателями" или по другому потребителями (consumers) позже разберёмся с этим подробнее.
Допустим, у тебя есть система с авторизацией. Чел зашёл значит событие произошло. И твой сервис отправляет это событие в кафку типо: "Окей, записываю это событие в Kafka, тема 'user-events'".
Что значит “тема”? Это как канал в Телеграме — не переживай, скоро объясню подробнее. После того как событие попало в кафку на другой стороне твои потребители (consumers) начинают читать сообщения “из твоего канала в тг” :)
И вот:
один потребитель пишет что то в лог
другой проверяет, не подозрительная ли активность
третий прогревает рекомендации
Все они реагируют на одно и то же событие, независимо друг от друга. И это круто.
Хочешь добавить логику? Просто подключаешь нового слушателя/потребителя (consumer).
Хочешь изменить старую? Не ломаешь другие части, меняешь что то конкретное
Хочешь увидеть, что было раньше? Возвращаешься назад и читаешь события заново.
Если по простому то
Kafka это как лента новостей внутри твоей системы. События туда пишутся, а подписчики читают. У кого то фильтр на "логины", у кого то на "покупки", а у кого то вообще всё подряд. Главное ты не теряешь ни одного события и всегда можешь к нему вернуться.
Ладно, у нас уже есть общее понимание, что Kafka — это такая себе лента новостей внутри системы которая в свою очередь является хребтом системы. Но кто пишет туда новости, а кто их читает?
Вот тут и появляются два ключевых персонажа (термина): продюсер (producer) и потребитель (consumer).
Продюсер (producer) — это просто код (или сервис), который отправляет события в Kafka. Он как бы говорит: «Вот, случилось что то важное на моей стороне, держи вот тебе новость об этом!».
Примеры:
Продюсер “Сервис логина/авторизации” отправляет событие user_logged_in
Продюсер “бекенд магазина” кидает событие order_created
Продюсер “микросервис доставки товаров” отправляет событие package_delivered
Технически, твой сервис (продюсер) вызывает Kafka API когда отправляет свои события и говорит кафке: «Кидай вот это событие в topic (позже узнаешь что такое topiс) user-events». Кафка получает этот запрос и хранит его столько сколько нужно.
Потребитель (consumer) — это код (скрипт/сервис), который читает события из Kafka. Как правило потребитель подписан на какой то определенную тему (topic). Он как бы сидит с блокнотиком и такой: «Ага, кто-то залогинился. Надо сделать то то. О, заказ оформили пора начислять кому то бонусы».
Примеры:
Потребитель “Аналитик” следит за активностью пользователей и подписан например на топик user_actions
Потребитель “Логгер” подписан на тот же топик user_actions и пишет например в базу данные о времени авторизации
Потребитель “Cистема рекомендаций” подписан на топик orders и реагирует на события покупок
Важно: у Kafka несколько consumers могут читать одно и то же. Никто никому не мешает. Каждый читает как ему удобно хоть в реальном времени, хоть потом, хоть с начала, хоть с середины, короче говоря с любого места. У каждого потребителя есть свои правила обращения к топикам поэтому они друг другу не мешают и если кто то подумал что события исчезают после того как были обработаны потребителями нет это не так по дефолту они не удаляются то есть несколько потребителей могут без проблем обращаться к топикам сколько нужно.
[ Продюсер “Сервис регистрации” ]
|
v
Kafka
|
--------------------------------------------------
| | |
v v v
[ (consumer) логов ] [ (consumer) уведомлений ] [ (consumer) безопасности ]
Один пишет, остальные читают. Всё асинхронно, никто никому не мешает.
Да. Kafka гарантирует порядок сообщений в пределах одного раздела (partition), но об этом чуть позже. Пока просто знай: если ты хочешь, чтобы все события от одного пользователя шли строго по порядку надо правильно выбирать ключ (об это тоже чуть позже).
Kafka не говорит тебе, что делать. Она просто принимает события и отдаёт их всем желающим. Тот кто отправляет события — это продюсеры. Тот кто их читает — это консьюмеры. Всё просто.
Если всё ещё кажется, что это сложно не парься. Мы постепенно всё разложим по полочкам. Дальше разберёмся, как эти события вообще организованы внутри Kafka: что такое топики (topics) и партиции (partitions), и зачем они нужны.
Ладно, с продюсерами и потребителями (producers / consumers) разобрались. Но куда именно они всё это шлют? И откуда потом читают?
Знакомься вот тебе еще три термина: тема (topic), раздел (partition) и позиция (offset) — три кита, на которых всё стоит.
Topic (тема) — это просто название канала, типа “user-events” или “orders”.
Ты как продюсер (producer) отправляешь событие в конкретный topic.
А потребитель (consumer) подписывается на этот topic и говорит: «Окей, я читаю всё, что приходит сюда».
Можно представить, что topic — это как канал в Телеграме куда хозяин этого канала отправляет сообщения а пользователи которые подписаны на этот канал читают эти сообщения и как то реагируют на них.
Окей, у тебя есть topic, но если туда летят миллионы событий нужно как то разделить поток на части. Вот аналогия. Представь что у канала в телеграмме есть разделы куда автор данного канала кидает сообщения то есть распределяет их.
Partition (раздел) — это кусок темы, отдельный лог-файл внутри Kafka. Каждый topic состоит из одного или нескольких partition'ов.
Пример: topic user-events может иметь 3 partition'а в которых находятся события:
Partition 0: [login, logout, login...]
Partition 1: [register, register, register...]
Partition 2: [click, click, click...]
Kafka сама решает, куда положить событие — по ключу или просто рандомно.
Зачем это нужно?
Параллелизм: несколько consumers могут читать разные partition'ы одновременно.
Масштабируемость: больше partition'ов = больше производительности. Типо индексации ключей в базах данных но это совсем не так просто аналогия для размышления :)
Отказоустойчивость: можно дублировать partition'ы на разные брокеры (об этом позже поговорим).
Offset (смещение) — это просто номер сообщения внутри partition (раздела). Вот аналогия: представь пользователя, который подписан на канал в Telegram. Он листает сообщения вверх или вниз — таким образом подгружаются новые или старые сообщения. Когда пользователь листает, он как бы передаёт Telegram'у offset — то есть сообщает: "Я сейчас нахожусь на таком то сообщении". В ответ Telegram присылает ему следующие сообщения, в зависимости от направления скролла — более новые или более старые.
Kafka не забывает события после чтения, то есть он их не удаляет в течении времени которые указаны в настройках кафки и каждый consumer сам помнит, до какого offset он дочитал.
Пример:
Partition 0: offset 0 = login
Offset 1 = logout
Offset 2 = login
Consumer может сказать: «Я остановился на offset 2» и потом продолжит оттуда.
Можно даже сказать: «Дай мне с самого начала» и прочитать весь поток заново.
[ Topic: user-events ]
├── Partition 0: login, login, logout
├── Partition 1: register, register
└── Partition 2: click, click, click
Каждый partition — это свой мини журнал, и у каждого события свой offset. Consumer сам решает, с какого места читать.
Topic — это общий канал событий
Partition — делит этот канал на независимые потоки (разделы)
Offset — показывает, где ты был в этом потоке
Kafka ничего не забывает. Ты всегда можешь «перемотать» назад, вперёд, или вообще начать сначала. Очень удобно для отладки, повторной обработки или восстановления данных.
Так, с топиками, партициями и offset'ами разобрались. А теперь возникает логичный вопрос: где всё это вообще живёт? Где Kafka всё это хранит? Кто за это отвечает?
Брокер (broker) — это просто один сервер на котором установлена Kafka, который:
принимает события от продюсеров (producers),
хранит их в темах (topics),
отдаёт их потребителям (consumers).
То есть, брокер — это работяга, который реально делает всю грязную работу: пишет логи, отдаёт данные, реплицирует, следит за партициями. Это обычный сервер. Или виртуалка. Или контейнер. Главное он крутит Kafka и слушает порты.
Один брокер — ок, но если:
у тебя миллион событий в секунду,
или ты не хочешь терять данные при падении сервера,
или хочешь масштабироваться...
...то тебе нужен кластер (cluster).
Кластер Kafka — это несколько брокеров, работающих вместе.
Пример: у тебя 3 брокера — Kafka разложит партиции между ними, и если один упадёт, другие продолжат работу.
Допустим, у тебя есть topic user-events с 3 partition'ами:
Partition 0 — на брокере 1
Partition 1 — на брокере 2
Partition 2 — на брокере 3
Kafka автоматически балансирует нагрузку и следит, чтобы всё работало.
Если брокер 2 упал Kafka передаёт лидерство по Partition 1 на другой брокер. Всё крутится дальше, данные не теряются.
Kafka умеет реплицировать партиции.
Например:
Partition 0 — основной на брокере 1, копия на брокере 2
Partition 1 — основной на брокере 2, копия на брокере 3
Partition 2 — основной на брокере 3, копия на брокере 1
Если что то падает, Kafka переключает потребителей и продолжает работать.
Это называется лидер (leader) и реплики (followers). Лидер — активный, реплики — на подстраховке. В рамках уровня 1 мы не будем рассматривать лидеров и реплики про это все будет разложено на уровне 2. Сейчас вам нужно просто понять что мы можем делать с партициями то есть мы можем их копировать, распределять между брокерами (серверами)
Брокер — это один сервер Kafka.
Кластер — это несколько брокеров, объединенных вместе.
Партиции раскидываются по брокерам.
Репликация защищает от потерь.
Kafka-кластер — это как муравейник. Каждый делает свою работу, но вместе — надёжная система, способная пережить сбои и выдержать огромную нагрузку.
Ты можешь удивиться, но Kafka — это не про “очередь и забыли”. Это про: «записал и сохранил, на случай если снова понадобится».
Именно поэтому Kafka — такая мощная штука. Она не выкидывает сообщения, как это делают обычные очереди. Она их бережно хранит.
Каждое сообщение, которое попадает в Kafka — сохраняется на диск. Не в базу данных. Не в оперативку. А в лог файл. Прям как log.txt, только гораздо умнее.
Каждый partition — это свой непрерывный журнал (log):
[ offset 0 ] -> сообщение 1
[ offset 1 ] -> сообщение 2
[ offset 2 ] -> сообщение 3
Никаких “удалили после прочтения”. Kafka бережёт всё.
Ты сам решаешь:
7 дней
3 часа
1 месяц
пока не кончится место на диске?
Kafka умеет хранить по времени или по размеру. Также есть режим compaction — оставлять только последнее событие по ключу.
Ты хочешь:
Перечитать всё сначала?
Поймать только свежак?
Перезапустить консьюмер с нужного места?
Kafka скажет: “Да не вопрос”.
Потому что consumer сам управляет offset'ом, и может читать с любого места. Это особенно круто, если у тебя что то сломалось или ты хочешь перегнать данные заново.
В очереди: сообщение пришло — один потребитель его съел всё, до свидания.
В Kafka:
можно читать одно и то же сообщение многим потребителям (consumers)
можно читать несколько раз
можно делать “перемотку” (rewind)
можно анализировать прошлое, как лог событий
Потому что:
Надёжно — можно восстановиться после сбоя
Удобно — можно подключать новых консьюмеров
Гибко — можно обрабатывать старые данные новыми способами
Kafka — это как чёрный ящик на борту самолета. Все события пишутся, и ты всегда можешь их прочитать.
Так вот, Kafka умеет то, чего не умеют обычные очереди: перематывать время назад. Не буквально, конечно. Можно перечитать события хоть с самого начала, хоть с любого места. Это возможно благодаря offset’у (смещению).
Каждое сообщение в Kafka имеет свой offset (смещение) — просто номер по порядку внутри partition’а. Типа:
Partition 0:
[ offset 0 ] → событие A
[ offset 1 ] → событие B
[ offset 2 ] → событие C
Или вот более понятнее: Consumer говорит: Я читаю из топика user_actions, из раздела (partition) 1, и я прочитал до offset 2 включительно. Следующее будет offset 3.
{
"topic": "user_actions",
"partition": 1,
"offset": 2
}
Вот реальные случаи, когда это нужно:
Ты выкатил багованный consumer и хочешь всё перечитать.
Появился новый сервис, и ему нужно пройтись по истории.
Ты тестируешь аналитику, и надо “прогнать события заново”.
Consumer упал, и ты не уверен, что всё было обработано.
Kafka тут как Ютюб — можешь поставить на паузу, перемотать, пересмотреть и т д.
Kafka хранит сообщения по умолчанию несколько дней (или сколько ты настроил). И consumer может сказать:
«Дай всё с самого начала»
«Дай только свежак»
Или вручную: «Дай с offset 123»
Важно: offset сохраняется отдельно — например, в БД можно хранить состояние твоих консьюмеров. И если что то случится с твоим консьюмером можно в любой момент востановить его состояние из базы данных.
У тебя лог событий:
[0] user_registered
[1] user_logged_in
[2] item_added_to_cart
[3] order_created
Ты дочитал до offset 2. А потом понял, что order_created куда то потерялся. Никаких проблем: просто говоришь Kafka — «перемотай на offset 2», и читаешь снова.
Итого:
Offset — это как закладка в книге.
Kafka не заставляет тебя читать по порядку — ты сам решаешь, откуда продолжать.
Можно читать заново, можно начать сначала, можно вручную задать точку.
Это мощнейшая фича, особенно если у тебя много данных и надо быть уверенным, что ничего не потеряно.
Так, события у нас уже летят в Kafka, хранятся, читаются. Но что, если мы хотим реагировать на них сразу, в момент появления? Не “сначала сохрани, потом проанализируй”, а “пришло — обработал — полетел дальше”?
Вот тут и вступает в игру то, что называется потоковая обработка (stream processing).
Потоковая обработка (stream processing) — это когда ты обрабатываешь данные прямо по ходу, не дожидаясь, пока наберётся пачка.
Это как диджей, который не записал плейлист заранее, а ставит треки прямо на ходу — под настроение публики. Каждый звук — это реакция здесь и сейчас. Никаких задержек, только поток.
Пользователь положил товар в корзину → событие item_added_to_cart ушло в Kafka.
В этот же момент:
Потребитель “сервис” показывает скидки на похожие товары.
Другой обновляет рекомендации.
Третий сразу пересчитывает общую сумму заказа.
И всё это в реальном времени. Без “сначала в базу, потом скрипт раз в минуту”.
Чем это отличается от обычной обработки?
Обычная обработка | Потоковая обработка |
Сохранили → потом обработали | Пришло → сразу обработали |
Периодические джобы, батчи | Реакция на каждое событие |
Задержка | Мгновенно (ну почти) |
Kafka сам по себе просто платформа событий. А вот для обработки потока у тебя есть инструменты:
Kafka Streams — Java библиотека для создания потоковых приложений. Прямо в коде пишешь: фильтруй, группируй, агрегируй, джойни. Для тех кто пишет на Java.
ksqlDB — то же самое, только с помощью SQL запросов. Очень удобно, если ты не хочешь писать код на java. К примеру ты можешь написать программу на Golang который будет отправлять SQL запросы в ksqlDB.
Пример SQL запроса на ksqlDB:
SELECT item, COUNT(*)
FROM cart_events
WINDOW TUMBLING (SIZE 1 MINUTE)
GROUP BY item;
Получаешь метрику: сколько раз за минуту добавляли каждый товар.
И что можно делать?
Считать метрики в реальном времени
Делать антифрод — отслеживать подозрительную активность
Триггерить уведомления
Собирать отчёты на лету
Реагировать на клики, заказы, лайки — без задержек
Мир ускоряется. Люди не хотят ждать.
Бизнесу важна реакция “здесь и сейчас”.
А batch обработка — это долго
Kafka + stream processing = реактивная, быстрая, гибкая система, которая живёт в потоке данных.
Окей, с теорией вроде разобрались. Но может быть всё это слишком сложно и не нужно? Зачем вообще тянуть Kafka в проект?
А вот сейчас — самое вкусное. Давай посмотрим, где Kafka реально используется, и главное зачем.
Ты заходишь на сайт, листаешь товары, кидаешь в корзину, оформляешь заказ.
Каждое действие — это событие, которое можно отправить в Kafka:
user_logged_in
product_viewed
item_added_to_cart
checkout_completed
А дальше на эти события реагируют твои потребители:
Сервис рекомендаций: показывает, что может ещё понравиться
Аналитика: считает конверсию, воронки, отказы
Нотификации: отправляет письма, пуши, смс
Биллинг: выставляет счета
И всё это — в реальном времени, без “отложенных джобов”.
Kafka обрабатывает события вроде:
transaction_created
payment_failed
atm_withdrawal
Тут начинается работа твоих потребителей:
Антифрод: ловит подозрительные транзакции (например, снятие с карты в 3 странах за минуту)
Оповещения: “Вы сняли 10 000 руб”
Аудит: всё логируется в неизменяемый журнал
Репликация: данные из одной базы летят в другую
Kafka — как труба, по которой летят события отовсюду:
frontend
backend
сторонние API
А дальше:
Обработка в реальном времени (ksqlDB)
Счётчики, метрики, графики
Реакция на всплески активности
Генерация отчётов
message_sent
user_typing
reaction_added
Kafka:
буферизует события
рассылает их подписчикам
логирует
позволяет строить цепочки реакций (например, лайк → уведомление → пуш)
каждые 5 секунд приходит температура
уровень воды, движение, ток, давление, скорость
Kafka собирает это всё в кучу, фильтрует, агрегирует, отправляет дальше. Можно строить:
live-дешборды
алерты (если что-то пошло не так)
реактивные сценарии (отключить что-то, если перегрев)
Kafka — это как лента событий внутри системы. Один сервис что то делает — другой на это реагирует. Всё пишется, всё хранится, всё можно перечитать. Это как централизованный «журнал жизни» твоей системы.
Это те, кто отправляет события в Kafka. Например, бекенд сервиса авторизации/регистрации шлёт user_logged_in, магазин шлёт order_created. Это просто отправка данных в нужную “тему(topic)”.
Это те, кто читает события из Kafka. Причём читать могут сколько угодно разных сервисов(consumers), независимо друг от друга. Один пишет — трое читают, и все по своему.
Это канал событий. Например: user-events, payments, logs. Все события по одной теме — в одном месте.
Тема делится на разделы (partition'ы), чтобы можно было:
параллельно обрабатывать данные,
распределять нагрузку,
масштабироваться.
Kafka пишет события в партиции, и каждый consumer читает конкретные разделы.
Offset — это позиция сообщения внутри партиции. Каждый consumer запоминает, на каком offset он остановился. Потом может продолжить или перечитать с нужного места.
Да! Это и есть одна из главных фич Kafka. Consumer может читать:
с самого начала (earliest)
только новое (latest)
с конкретного offset
Это просто сервер на котором установлена Kafka, который хранит и обрабатывает события. Kafka может работать на одном брокере, но в реальных системах используется кластер из нескольких брокеров на каждом из них установлен экземпляр кафки.
Чтобы было надёжно и масштабируемо. Один брокер упал — другие продолжают работать. Kafka раскидывает данные по брокерам, всё живёт в распределённой среде.
Нет! Kafka хранит их столько, сколько ты скажешь. По времени или по размеру. Можно читать одно и то же сообщение хоть сто раз.
Это когда события обрабатываются сразу, в момент поступления. Без задержек, без батчей. Kafka может работать с Kafka Streams или ksqlDB — ты можешь фильтровать, агрегировать, соединять события прямо в потоке. Kafka Streams — это Java only. Но ты можешь писать обычных consumer'ов на Go, Python, Node.js и т.д. А если хочешь стриминг без кода — есть ksqlDB с SQL запросами.
Давай представим:
Ты видишь город, где вместо улиц — потоки данных, а здания — это сервисы. В центре города — большое здание Kafka, как центральная станция или хаб, из которой расходятся трубопроводы событий во все направления.
Kafka — гигантское здание в центре, дата-хаб, похожее на распределённую станцию метро или аэропорт.
Topics — как перроны, на каждом — движутся “событийные поезда”. Каждый поезд — это цепочка сообщений, движущихся по своим рельсам (partition'ам).
Producers — это районы города, откуда отправляются “поезда”. Например:
Район логинов
Район покупок
Район доставки
Их “поезда” прибывают на соответствующие платформы (topics).
Consumers — это другие здания: склады, фабрики, бизнес-центры. Они подключены к перронам трубами и получают события в реальном времени.
Offset — это как цифровые табло: у каждого здания (consumer) есть счётчик — показывает, какой поезд (offset) он уже обработал.
Кластер брокеров — это как сеть серверных ангаров, под городом. Там хранятся все поезда, архивы событий, копии и бэкапы (репликация).
Kafka — инфраструктура, а не просто очередь.
Она объединяет весь “город” микросервисов в единую экосистему.
Данные не просто хранятся, а движутся, и Kafka — логистика этой архитектуры.