Раздел 6A. Очередь против лога — Kafka, Cassandra и догон по курсору
Транзиентная очередь (Kafka) против durable-лога (Cassandra); запись всегда идёт в лог; курсор клиента решает, откуда читать пропущенное.
Раздел 6 объяснил, как сообщение не теряется и приходит по порядку. Но остался вопрос на стыке: где сообщение физически ждёт, пока получатель офлайн, и откуда его потом достают, когда он вернулся? Тут работают два разных хранилища, и путать их роли — классическая ошибка на интервью.
Два хранилища, две роли
Очередь (Kafka) — транзиентный буфер
- Транзиентный = временный, «полежало и исчезло».
- Хранит сообщения ограниченное время (дни — настраивается), потом удаляет.
- Это труба для свежего, а не склад.
- 📦 Аналогия: лента выдачи багажа — чемоданы едут, но не забрал — через время их снимут.
Лог (Cassandra) — durable-архив
- Durable = надёжный, «легло навсегда».
- Хранит всю историю — это источник правды.
- 📦 Аналогия: камера хранения — лежит сколько надо, по твоему номеру всегда найдут.
💡 Транзиентный = на время. Durable = навсегда. Если услышала «транзиентный» — мысленно подставь «временный».
Правило записи: лог получает всё и всегда
Алиса отправила сообщение
↓
1. ВСЕГДА → Cassandra (durable-лог) ← святое, источник правды
↓
2. Боб офлайн? → ДОПОЛНИТЕЛЬНО в очередь Kafka + пуш, чтобы разбудить
Боб онлайн? → сразу толкаем ему, очередь не нужна
📌 Cassandra получает всё и всегда. Kafka — только как временный буфер для офлайна. Поэтому полная история гарантированно есть в логе, а в очереди — лишь «свежак для тех, кто ещё не забрал».
Правило чтения: курсор решает, откуда брать
Решает клиент при переподключении — он присылает свой курсор «докуда я уже видел»:
Боб вернулся → "я видел до seq 4012, что дальше?"
↓
Нужное (4013+) ещё лежит в Kafka?
↓
┌────┴───────────────────┐
↓ ДА ↓ НЕТ
(короткий разрыв, (долго офлайн / новое устройство /
свежак под рукой) старое уже протухло в Kafka)
↓ ↓
отдаём из очереди, Sync-сервис дочитывает из Cassandra
быстро ✅ по курсору: "всё после 4012" ✅
Критерий простой: есть ли нужное ещё в Kafka? Есть → берём оттуда (быстро). Нет → идём в Cassandra (надёжно).
Почему догон читают из Cassandra, а не из Kafka
1. Kafka хранит недолго. Боб офлайн месяц → в очереди уже пусто, всё протухло. В логе — лежит.
2. Новому устройству нужна вся история. В Kafka её давно нет, Cassandra отдаёт хоть с первого сообщения.
3. Kafka — лента «по порядку», а догон — точечный запрос. «Дай чат №555 начиная с seq 4012» — это родной запрос Cassandra (она шардирована по chat_id), а Kafka заставила бы листать всю ленту.
4. У каждого устройства свой курсор. Телефон видел до 4012, десктоп — до 3500. Каждому нужен свой произвольный диапазон, повторно. Лента Kafka для этого не годится, а из лога читай что угодно сколько угодно раз.
Зачем тогда вообще Kafka, если есть Cassandra
Разделение ролей под разную нагрузку:
| Очередь (Kafka) | Лог (Cassandra) | |
|---|---|---|
| Роль | быстро толкнуть «есть новое», разбудить | вечный источник правды |
| Срок хранения | дни (транзиентно) | всегда (durable) |
| Тип запроса | поток по порядку | точечно: чат + диапазон |
| Кто читает | живая доставка онлайн | Sync при догоне |
Короткий разрыв (метро) → быстро из Kafka (свежак под рукой)
Долгий офлайн / новый телефон → надёжно из Cassandra через Sync
💡 Cassandra — дефолт и страховка (там есть всё). Kafka — ускорение для частого случая, чтобы не дёргать архив по пустякам.
Главное, что сказать на собеседовании
- Запись всегда идёт в durable-лог (Cassandra) — источник правды. В очередь Kafka — дополнительно, если получатель офлайн.
- Очередь транзиентна — буфер на дни, не вечное хранилище.
- Курсор клиента решает, откуда читать: свежее ещё в Kafka — оттуда; протухло или новое устройство — догон из Cassandra через Sync.
- Почему не всё из Kafka: долгий офлайн и новые устройства, плюс Kafka — лента, а догон — точечный запрос по чату и диапазону.
- Почему не всё из Cassandra напрямую: Kafka даёт быстрый сигнал «есть новое» и дешёвую доставку свежего онлайн-получателям.