Kembali ke jurnalCATATAN FAJAR
Software Engineering7 menit baca

Kafka atau Redis Streams: Gimana Cara Memilihnya

Memilih antara Kafka dan Redis Streams dengan mengecek kebutuhan ordering, replay, recovery, kapasitas, dan operasional.

BAGIAN 16 DARI 16Kafka vs Redis Streams
  1. 01Kafka vs Redis Streams: Bikin Stock Ticker Dua Kali
  2. 02Kafka Partition dan Key: Menjaga Simbol Tetap Berurutan
  3. 03Dasar-Dasar Redis Streams: XADD, Entry ID, dan MAXLEN
  4. 04Kafka Consumer Group: Lag, Draining, dan Rebalancing
  5. 05Consumer Group Redis Streams: Competing Consumer dan PEL
  6. 06At-Least-Once di Kafka: Retry dan Dead Letter Queue
  7. 07Redis Streams: Message Nyangkut, XAUTOCLAIM, dan Dead Letter
  8. 08Exactly-Once di Kafka: Idempotent Producer dan Transaction
  9. 09Redis Pub/Sub vs Streams: Ephemeral atau Durable
  10. 10Co-Partitioning: Key Sama, Partition Sama, di Kedua Topic
  11. 11Menulis Custom Partition Assigner KafkaJS untuk Local Join
  12. 12Kafka ISR vs Redis Cluster: Replication dan Failover
  13. 13Stateful Streams: Trigger Edge vs Level dan Window OHLC
  14. 14Membangun Live Market Dashboard dengan SSE dan Next.js
  15. 15Benchmark Kafka vs Redis Streams: Throughput dan Latency
  16. 16Kafka atau Redis Streams: Gimana Cara MemilihnyaKamu di sini
Di artikel ini 11 bagian

Lima belas post yang lalu, saya memulai perbandingan sistem untuk price tick dan threshold alert. Saya membangun ticker-nya dua kali, dengan Kafka dan Redis Streams yang jalan di Docker. Eksperimen-eksperimen itu memberi saya perilaku konkret untuk dibandingkan.

Post terakhir ini menghubungkan keenam belas artikel itu ke sebuah pilihan arsitektur.

Setiap klaim punya link ke post tempat saya melihatnya terjadi langsung di broker yang jalan, bukan sekadar mengklaimnya dari ingatan. Post ini bisa dibaca sendiri, dengan link ke setiap eksperimen sebagai buktinya.

Keduanya menyebut diri "a log with consumer groups"

Kafka dan Redis Streams berbagi kosakata di permukaan: append only log, consumer group, offset, acknowledgment. Di baliknya, keduanya dibangun untuk failure mode yang berbeda dan budget yang berbeda, jadi justru kata-kata yang sama itulah yang bikin pilihannya membingungkan.

DimensiKafkaRedis Streams
StorageLog yang durable di disk, di-retain berdasarkan waktu atau ukuranDi memory, di-trim dengan MAXLEN, AOF/RDB opsional
Unit paralelismePartition, urutan terjaga per partitionSatu stream adalah satu log yang terurut, kamu sendiri yang men-shard key
Model consumer groupKepemilikan partition, sticky, menjaga urutan per keyCompeting consumer, work queue, nggak ada urutan per key
Default deliveryAt-least-once, exactly-once lewat transactionAt-least-once lewat PEL, XACK, XAUTOCLAIM
Latency umumSingle digit ms yang rendahSub-millisecond
Retention dan replayFirst class, rewind ke offset mana punHistory sampai di-trim, replay lewat XRANGE
Footprint operasionalSebuah cluster: broker, KRaft, replicationRedis yang mungkin udah kamu jalankan

Tabel ini adalah panduan kualitatif. Rentang latency di dalamnya bukan hasil pengukuran dari eksperimen-eksperimen ini, dan bukan juga batas yang dijamin oleh salah satu sistem. Delivery dan durability juga bergantung pada perilaku dan konfigurasi client.

Durability dan retention

Kafka menyimpan log di disk. Kemampuannya bertahan dari kegagalan bergantung pada konfigurasi replication, acknowledgment, dan storage. Redis Streams memakai memory, dengan persistence lewat AOF atau RDB kalau dikonfigurasi.

Retention itu keputusan terpisah. Trimming dengan MAXLEN, seperti di post fundamentals, membatasi history yang tersedia. Tentukan history yang dibutuhkan dan budget memory sebelum memakai sebuah stream sebagai catatan yang otoritatif.

Tanyakan apakah kamu perlu me-replay history, meng-audit apa yang terjadi minggu lalu, atau mem-backfill consumer baru dari tiga hari yang lalu. Kafka menjawab itu secara struktural. Redis cuma bisa menjawabnya sejauh apa pun yang kamu pilih untuk disimpan di RAM.

Throughput dan fan out

Kafka bisa menyimpan volume data yang melebihi RAM, sedangkan Redis Streams menyimpan entry yang di-retain di memory. Throughput dan latency perlu diukur dengan workload-nya. Artikel benchmark menjelaskan harness lokal dan batasannya. Tes dengan hardware dan payload yang representatif sebelum mengambil keputusan deployment.

Untuk mengirim update ke banyak client, Redis menyediakan Streams dan Pub/Sub. Streams menyimpan entry untuk dibaca belakangan lewat command seperti XRANGE. Pub/Sub cuma mengirim ke subscriber yang terhubung dan nggak punya history yang disimpan. Redis Pub/Sub vs Streams membandingkan perilaku-perilaku ini.

Consumer group Kafka membaca record yang di-retain secara independen. Setiap group melacak posisinya sendiri. Client yang cuma butuh state terkini mungkin nggak butuh history event yang disimpan.

Ordering dan partitioning

Ticker-nya memakai symbol sebagai key Kafka dan 6 partition di market-updates. Tick BBCA dipetakan secara konsisten selama jumlah partition dan partitioner-nya nggak berubah. Kafka Partitions, Keys, and Ordering menjelaskan mapping murmur2-nya. Penambahan jumlah partition bisa mengubah tujuan record berikutnya. Rencanakan perubahan itu sebelum mengandalkan urutan yang berkesinambungan untuk sebuah key.

Satu stream Redis adalah satu log yang terurut. Untuk mendistribusikan data ke beberapa node, aplikasi bisa memakai beberapa stream key. Redis Cluster memakai CRC16 untuk memilih slot-nya. Hash tag bisa menaruh key yang saling terkait di slot yang sama. Beberapa consumer bisa memproses satu stream secara konkuren, tapi urutan selesainya bisa beda dari urutan entry.

Kafka Consumer Groups dan Redis Streams Consumer Groups and the PEL menjelaskan kepemilikan dan delivery. Co Partitioning menyelaraskan key yang cocok di market-updates dan notifications. Local join juga butuh consumer assignment yang cocok dan state lokal yang udah diinisialisasi.

Jaminan delivery

Kedua sistem bisa mengulang delivery, jadi consumer butuh efek yang idempotent. Di Kafka, saya commit setelah handling berhasil dan me-route kegagalan yang terus berulang ke DLQ. Artikel soal retry menjelaskan policy itu.

Kafka transaction bisa meng-commit output dan source offset bersamaan kalau keduanya tetap di Kafka. Saya menguji batasan itu di artikel soal transaction. Batasan itu nggak mencakup efek eksternal.

Consumer group Redis menyimpan entry di PEL sampai XACK. Aplikasi bisa memakai XAUTOCLAIM dan delivery count untuk recovery dan batas retry. Artikel soal recovery menjelaskan proses itu. Redis bisa menggabungkan command output dan acknowledgment secara atomic dalam batasan key-nya, tapi protokol pemrosesan dan deduplikasi tetap jadi tanggung jawab aplikasi.

Beban operasional

Deployment Kafka butuh broker dan pengelolaan metadata. Setting replica dan ISR menentukan kegagalan broker mana yang bisa ditoleransi. Saya menguji leader failure di Kafka ISR vs Redis Cluster Sharding.

Redis Cluster mendistribusikan 16384 hash slot ke beberapa node. Satu instance Redis juga bisa menampung stream. Deployment Redis yang udah ada mungkin mengurangi pekerjaan setup, tapi durability dan kapasitas queue tetap perlu ditinjau. Biaya operasionalnya tergantung pada apa yang udah dijalankan tim dan apa yang bisa didukungnya.

Pengalaman tim memengaruhi biaya operasional. Runbook, monitoring, dan prosedur upgrade yang udah ada mengurangi pekerjaan yang dibutuhkan untuk mendukung sebuah sistem. Saya ikut memperhitungkan biaya itu waktu platform baru kelihatannya lebih cocok untuk workload-nya.

Kapan Redis Streams udah cukup

  • Kamu udah menjalankan Redis dan nggak mau menambah infrastruktur.
  • Volumenya sedang dan kamu nggak keberatan men-trim dengan MAXLEN.
  • Bentuk masalahnya adalah work queue: competing consumer, ack, retry, tanpa urutan per key yang ketat.
  • Latency serendah mungkin lebih penting daripada retention yang panjang atau replay.
  • Kamu butuh fan out real time dan bisa memilih dengan sadar antara Streams (durable) dan Pub/Sub (ephemeral).

Kapan Kafka sepadan dengan kompleksitasnya

  • Kamu butuh history yang durable dan bisa di-replay: audit, reprocessing, mem-backfill consumer baru dari beberapa hari yang lalu.
  • Kamu butuh ordering per key yang tetap terjaga di banyak consumer sekaligus, bukan cuma di satu worker.
  • Pipeline-nya butuh read process write yang exactly once, lebih dari sekadar idempotency yang hati-hati.
  • Throughput-nya tinggi dan berkelanjutan, atau volume data yang melebihi RAM adalah batasan desain, bukan edge case.
  • Kamu mau ekosistem di sekitarnya: connector, framework stream processing, schema registry, semua tooling yang dibangun di sekitar commit log yang durable sebagai source of truth.

Hybrid yang pragmatis

Ticker saya memakai kedua sistem. Redis menangani delivery alert yang langsung, sedangkan Kafka menyimpan history event untuk diproses belakangan. Pembagian ini bikin setiap consumer bisa memakai history yang dibutuhkannya.

mermaid
graph LR
    T[Price tick] --> MU["Kafka: market-updates (durable log)"]
    MU --> S["Derived state: OHLC windows + alert evaluation"]
    S -->|"alert crosses threshold"| N["Redis: notification fan-out"]
    N --> D1[User device]
    N --> D2[User device]

Di desain saya, Kafka menyimpan data market untuk replay. Redis mendukung delivery alert ke client yang terhubung. Pilihan ini mencerminkan peran masing-masing komponen, bukan keunggulan latency yang terukur.

Stateful Stream Processing membahas window OHLC dan evaluasi alert. Artikel dashboard SSE membahas delivery ke browser.

Checklist keputusan

Seluruh seri ini, dipadatkan jadi satu alur:

mermaid
graph TD
    A[Pick the event backbone] --> B{"Need replay, audit, or backfill?"}
    B -->|Yes| K1[Kafka]
    B -->|No| C{"Order preserved per key, across many consumers?"}
    C -->|Yes| K2[Kafka]
    C -->|No| D{"Need exactly-once read-process-write?"}
    D -->|Yes| K3[Kafka]
    D -->|No| E{"Throughput huge and sustained, data will outgrow RAM?"}
    E -->|Yes| K4[Kafka]
    E -->|No| F{"Already running Redis for something else?"}
    F -->|Yes| R1[Redis Streams]
    F -->|No| G{"Team comfortable operating a Kafka cluster?"}
    G -->|No| R2[Redis Streams]
    G -->|Yes| H["Either works, pick the one your team knows"]

Flowchart ini memakai replay, ordering, batasan transaction, batas memory, dan pengalaman operasional yang udah ada. Kebutuhan-kebutuhan ini membantu menjelaskan pilihan untuk workload tertentu.

Eksperimen-eksperimen ini makan waktu lebih lama daripada sebuah tabel perbandingan, tapi membantu saya memahami perilakunya. Saya mengamati key ordering, rebalance, handling DLQ, dan kegagalan broker. Saya juga menguji custom partition assigner yang menjaga partition topic yang saling terkait tetap di satu proses.

Saya bakal memilih berdasarkan kebutuhan retention, ordering, dan recovery lebih dulu. Eksperimen-eksperimen itu bikin saya lebih gampang menghubungkan kebutuhan tersebut ke sebuah sistem.

Kalau kamu pernah menjalankan salah satunya di skala yang belum pernah saya coba, saya pengin tahu di titik mana framework ini nggak berlaku lagi. Itu bagian yang nggak bisa saya pelajari dari sebuah laptop.

TOPIK

MAKASIH UDAH BACA

Gimana menurutmu?

Reaksi atau obrolan, dua-duanya selalu ditunggu.

Memuat reaksi…

Bagikan

Memuat komentar...

LANJUT JELAJAH

Satu pikiran bawa ke pikiran lain.

Semua tulisan
Kembali ke semua tulisanSatu catatan, pelan-pelan.