Курс «Архитектура мессенджера» · Часть 2 · Соединение и доставка

Раздел 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 — ускорение для частого случая, чтобы не дёргать архив по пустякам.


Главное, что сказать на собеседовании

  1. Запись всегда идёт в durable-лог (Cassandra) — источник правды. В очередь Kafka — дополнительно, если получатель офлайн.
  2. Очередь транзиентна — буфер на дни, не вечное хранилище.
  3. Курсор клиента решает, откуда читать: свежее ещё в Kafka — оттуда; протухло или новое устройство — догон из Cassandra через Sync.
  4. Почему не всё из Kafka: долгий офлайн и новые устройства, плюс Kafka — лента, а догон — точечный запрос по чату и диапазону.
  5. Почему не всё из Cassandra напрямую: Kafka даёт быстрый сигнал «есть новое» и дешёвую доставку свежего онлайн-получателям.