Брокери повідомлень
1) Навіщо брокери повідомлень
Брокер розв'язує продюсерів і консюмерів за часом/швидкістю/надійністю:- Буферизація і згладжування піків, бекпрешер.
- Масштабування читання/запису незалежно.
- Спостережуваність і відтворення (replay) подій.
- Архітектурні патерни: event-driven, CQRS, event sourcing, outbox/inbox.
2) Базові моделі та терміни
2. 1 Kafka (лігва модель)
Топік → партії (впорядковані логи) → офсети у консюмерів.
Consumer Group: паралелізм читання, балансування партій.
Ретеншн за часом/обсягом; компакція по ключу.
Семантика: мінімум - at-least-once, при налаштуваннях - effectively exactly-once (ідемпотентні продюсери + транзакції).
Порядок: гарантується всередині партії.
2. 2 NATS (теми/subjects, низька затримка)
Subject (тема) з ієрархією і вайлдкартами ('foo.','foo. >`).
Режими: pub/sub, queue-groups (фан-аут з розподілом роботи), request-reply (швидкий RPC).
Core NATS - ефемерний, наднизька латентність; JetStream - персистентність/ретеншн/повтори.
Порядок: кращий-зусиллям, без сильної глобальної гарантії; з JetStream - впорядкування на стрімі, але можливі рідкісні перевпорядкування при відмовах.
3) Семантики доставки та узгодженість
Ідемпотентність і дедуп - відповідальність програми/сінка, навіть при «exactly-once» в Kafka.
4) Порядок, партіонування та ключі
Kafka
Вибір ключа повідомлення визначає партію → сильний локальний порядок.
Ключі: `aggregate_id`, `tenant_id`, `order_id`. Уникайте гарячих ключів.
Баланс: N партій ≈ рівень паралелізму читання.
NATS
У Core баланс робить queue-group.
У JetStream Stream шардингується по subjects; упор на широку фан-аут/фан-ін з малою затримкою.
5) Ретеншн, реплей і компакція
Kafka
Retention: `retention. ms/bytes`.
Compaction: зберігає «останнє значення по ключу» (підходить для снапшотів/кешів/саг).
Replay: будь-який консюмер може «відмотати» офсети.
JetStream
Streams: файлові/меморі бекенди, політика зберігання за часом/байтами/кількістю повідомлень.
Consumers: pull/push, durable/ephemeral, фільтр за subject-префіксами.
Replay: redelivery або читання з початку/offset-like (sequence).
6) Транзакції, outbox і узгодженість
Kafka
Idempotent Producer (`enable. idempotence=true`): Захист від дублів.
Transactions: атомарний запис декількох партій + коміт consumer-offsets → патерн read-process-write без «дірок».
Transactional Outbox: запис бізнес-події та outbox-рядка в одній БД-транзакції, воркер публікує в Kafka.
NATS
Немає «міжстримових» транзакцій як в Kafka; використовуйте outbox/inbox та ідемпотентні консюмери (ключі, дедуп-стор).
7) RPC і запит-відповідь
Kafka для RPC незручна (високий overhead, порядок/відповіді складніше). Використовуйте асинхронні команди/події.
NATS: ідеальний для request-reply (мілісекунди, кореляція, таймаути).
go resp, err:= nc. Request("profile. get", []byte(`{"id":42}`), 200time. Millisecond)
8) Експлуатація і топології
8. 1 Kafka
Кластер: брокери + ZooKeeper (до старих версій) або KRaft (нова метадата).
Реплікація: RF≥3 по зонах, ISR/контролери.
Мультирегіон: MirrorMaker 2/Cluster Linking; актив-пасив/актив-актив з конфлікт-політиками.
Дискова/мережева ємність: вважати з'throughput × retention × replicas'.
8. 2 NATS
Cluster: багато вузлів, super-cluster (георозподіл), leafnodes для периферії/edge.
JetStream: розміщення стрімів по наборах вузлів (placement), реплікація (R = 1.. 5).
WAN: передбачувано низькі затримки, легка федерація.
9) Безпека
Kafka
TLS (mTLS), SASL: SCRAM, OAuthBearer.
ACL на топіки/групи/транзакції.
Шифрування «в спокої» (OS/диски) + мережеві політики.
NATS
nkey/JWT ідентичності, оператор-акаунти, пер-subject ACL.
mTLS між вузлами та клієнтами.
Ізоляція орендарів (accounts) + ліміти.
10) Спостережуваність та експлуатаційні метрики
Kafka
Брокер: `BytesIn/Out`, `RequestQueue`, `UnderReplicatedPartitions`, GC/FS stats.
Топік/партія: 'logEndOffset', consumer lag (критично).
Продюсер/консюмер: ретраї,'batch. size`, `linger. ms`, `fetch. min. bytes', помилки.
Інструменти: JMX, Cruise Control (ре-баланс), Schema Registry.
NATS/JetStream
Сервер: conn/msgs/sec, RTT, CPU/mem, slow consumer детекція.
JetStream: per stream/consumer — lag, redeliveries, acks, storage bytes.
Моніторинг: вбудований endpoint, nsc/adm-CLI, дашборди.
11) Продуктивність і тюнінг
Kafka
Великі батчі і'linger. ms'покращують throughput і стискають p99.
Компресія (lz4/zstd) економить мережу/диск.
num. partitions за кількістю споживачів/ядер, але не перегинати (overhead).
Диски: NVMe кращі, XFS/EXT4 з'noatime'.
NATS
Дрібні повідомлення, багато з'єднань - норма; тримайте queue groups «широкими».
JetStream: tune `max_ack_pending`, pull vs push, size of batches.
Backpressure: `FlowControl`, `IdleHeartbeat`, server-side limits.
12) Патерни інтеграції
Outbox/Inbox (і в Kafka, і в NATS).
SAGA: оркестрація подіями; дедуп по'saga _ id + step'.
Change Data Capture (CDC): Debezium → Kafka; в NATS - патерн «publisher з БД-тригерів/логів».
Stream processing: Kafka Streams/Flink/Spark; в NATS - сторонні процесори/функції, JetStream consumers.
Dead Letter Queue (DLQ) і retry-політики (експоненціальний backoff + jitter).
13) Приклади конфігурацій
13. 1 Kafka: створення топіка і продюсер
bash kafka-topics. sh --create --topic orders \
--partitions 12 --replication-factor 3 \
--config cleanup. policy=delete \
--config retention. ms=604800000 # 7d
properties producer. properties bootstrap. servers=broker:9092 acks=all enable. idempotence=true batch. size=65536 linger. ms=10 compression. type=zstd
13. 2 Kafka Streams: ідемпотентна обробка (ескіз)
java builder. <String, Order>stream("orders")
.groupByKey()
.aggregate(/... /)
.toStream()
.to("orders-agg");
13. 3 NATS JetStream: stream + consumer (nats CLI)
bash nats stream add ORDERS --subjects "orders. " --retention limits \
--storage file --max-bytes 100GB --replicas 3 --discard old
nats consumer add ORDERS ORDERS-WORKERS --filter "orders. created" \
--deliver pull --ack explicit --max-deliver 6 --backoff "1s,5s,30s,2m"
13. 4 NATS Request-Reply (Go)
go nc, _:= nats. Connect("tls://nats:4222", nats. Secure(tlsConf))
sub, _:= nc. QueueSubscribe("calc. sum", "workers", func(m nats. Msg) {
//... process...
m. Respond([]byte("42"))
})
14) Вибір Kafka vs NATS: швидкий орієнтир
Потрібен реплей, тривалий ретеншн, компакція, важкі стрім-процеси → Kafka.
Потрібен швидкий RPC, фан-аут/фан-ін з мікролатентністю, проста експлуатація, edge/IoT → NATS (Core).
Потрібна персистентність + фан-аут, але без важкої «лігвої» платформи → NATS JetStream.
Суворий порядок по ключу і транзакції → Kafka.
15) Планування ємності (спрощено)
Kafka
1. Пропускна: `inbound_MBps × RF × retention_days × 86400` → диски.
2. Партії: 'target _ concurrency'× запас 1. 5–2×.
3. Мережа: p99 + реплікація + продюсер компресія.
NATS/JetStream
1. Повідомлення/сек і середній розмір → throughput.
2. Retention×replicas → storage.
3. Ліміти consumers (ack-pending, redeliveries), CPU на серіалізацію.
16) Безпечна експлуатація: чек-лист
- TLS/mTLS включений, секрети ротуються.
- ACL/акаунти/квоти (per-tenant).
- Ідемпотентність на консьюмерах, DLQ і ретраї з джиттером.
- Моніторинг lag/throughput/помилок; алерти на URP (Kafka), redelivery-шторм (NATS).
- Capacity dashboards: партії, storage, p99.
- Тести на відмову вузлів/зони, game-days, реплей/бекфіл.
Документовані ключі партіонування та схеми (Schema Registry/JSON Schema).
- Політики ретеншну/компакції/TTL узгоджені з комплаєнсом.
- Версії брокерів/клієнтів регулярно оновлюються; сумісність wire-протоколу перевірена.
17) Анти-патерни
Гарячий ключ (всі події одного ID) → один «киплячий» потік. Шардуйте/буферизуйте.
Ретраї без ідемпотентності → дубль-ефекти.
Величезні повідомлення (MB-десятки) → фрагментація/паузи GC. Зберігайте payload в об'єктному, посилайте посилання.
Змішування RPC і стрімінга в Kafka → складний життєвий цикл/порядок.
JetStream як «довготривалий DWH» → не за призначенням; зберігайте довго в об'єктних/колонкових сторах.
Немає DLQ → «отруйні» повідомлення крутяться нескінченно.
Забутий ретеншн → диски заповнені, зупинка кластера.
18) FAQ
Q: Чи можна зробити «exactly-once» в кінці пайплайна?
A: На практиці - ефективно так: Kafka (ідемпотентний продюсер + транзакції) та ідемпотентні синки (ключ, upsert). У NATS - через ідемпотентність/дедуп в додатку.
Q: Що вибрати для мільйона дрібних RPC/сек?
A: NATS Core: мікролатентність, request-reply, легкі коннекти і queue-groups.
Q: Потрібна компакція і снапшоти стану?
A: Kafka с `cleanup. policy = compact', ключ = агрегат/ресурс.
Q: Як боротися з лагом?
A: Збільшити число партій/воркерів, зменшити час обробки, батчі і prefetch, оптимізувати десеріалізацію, вертикально посилити брокери/диски.
Q: Багаторегіон і DR?
A: Kafka - MirrorMaker 2/Cluster Linking, актив-пасив з RPO≈sekundy. NATS — supercluster/leafnodes; JetStream дзеркалювання/репліки по зонах.
19) Підсумки
Kafka і NATS закривають різні режими: Kafka - довговічні журнали подій, високий throughput, транзакційність і реплей; NATS - надлегка шина для низьких затримок, RPC і простого фан-ауту, з JetStream для персистентності. Вибір робіть від семантики доставки, порядку і ретеншну, латентності та операційних витрат. Спроектуйте ключі/партії, ретеншн, DLQ і спостережуваність - і ваша подієва архітектура буде передбачуваною, масштабованою і надійною.