Lesson 0016 · System Design · Modul Asinkron · ±20 menit

Message queue vs pub/sub; log (Kafka) vs broker (RabbitMQ)

Kenapa sebagian pekerjaan sebaiknya tidak ditunggu, dua cara mengantar pesan, dan dua keluarga produk yang paling sering disebut di interview

Sebelumnya, lesson 0015 menutup modul Caching: cache mengurangi kerja yang berulang. Modul Asinkron membahas kerja yang tidak perlu ditunggu. Lesson ini memberi kosakata dasarnya: queue, pub/sub, consumer group, log, dan broker.

Target lesson ini: Anda bisa menjawab "Kapan memakai message queue, kapan pub/sub, kapan Kafka, kapan RabbitMQ, dan kapan tidak memakai keduanya?" tanpa catatan, dalam 60 detik: alasan asinkron, satu pesan ke satu consumer vs ke semua subscriber, log yang bisa dibaca ulang vs pesan yang dihapus setelah ack, dan alternatif yang lebih murah.

1. Kenapa asinkron

Bayangkan endpoint checkout yang, setelah menyimpan pesanan, memanggil layanan email secara sinkron. Kalau layanan email butuh 5 detik, user menunggu 5 detik untuk sesuatu yang tidak ia lihat. Kalau layanan email mati, checkout ikut gagal. Message queue memutus ketergantungan ini: checkout menaruh pesan "kirim email untuk order 42" lalu langsung menjawab user, dan worker di belakang mengambil pesan itu kapan pun ia siap. Azure Architecture Center merangkumnya: message queue "decouple senders from consumers and prevent the sender from blocking a process while it waits for a response." [1]

Checkout (producer)→ Queue→ Worker email (consumer)→ SMTP

Tiga istilah dasar: producer mengirim pesan, broker (server queue) menyimpannya, consumer mengambil dan memprosesnya. Yang dibeli dengan asinkron adalah waktu respons dan isolasi kegagalan; yang dibayar adalah komponen baru, hasil yang tidak langsung terlihat, dan pertanyaan baru: bagaimana kalau pesan hilang atau datang dua kali (lesson 0017).

2. Message queue vs pub/sub

Dua pola pengantaran ini sering tertukar. Bedanya ada pada berapa penerima per pesan.

Queue: satu pesan → satu consumer Producer Queue Worker 1 Worker 2 Worker 3 pesan A ke W1, B ke W2, C ke W3 Pub/sub: satu pesan → semua subscriber Publisher Topik Email Stok Analitik pesan A ke ketiganya
Garis putus-putus = asinkron. Kiri: competing consumers. Kanan: publish-subscribe.
Message queue (point-to-point)Pub/sub
Penerima per pesanSatu consumer; consumer lain mengambil pesan berikutnyaSetiap subscriber mendapat salinan
Dipakai untukMembagi kerja: kirim email, resize gambar, generate PDFMemberi tahu banyak pihak: OrderPlaced ke email, stok, analitik
Menambah consumer berartiThroughput naik (kerja dibagi)Satu penerima baru, tanpa mengubah publisher

Queue dengan banyak consumer disebut competing consumers: sistem harus memastikan "each message is delivered to only one consumer." [2] Pub/sub punya "a mechanism for copying each message from the input channel to the output channels for all subscribers interested in that message." [1] Satu catatan penting untuk keduanya: urutan penerimaan "isn't guaranteed" kecuali broker mendukung urutan per partition atau session. [1]

Latihan 1 — Queue atau pub/sub

Jawab tanpa scroll ke atas. Soal yang sama akan muncul lagi, diacak, di review 0026.

Kuis di lesson ini adalah feedback cepat, bukan bukti penguasaan; yang dicatat hanya hasil review 0026.

3. Log (Kafka) vs broker (RabbitMQ)

Di interview, "pakai queue" biasanya disusul "Kafka atau RabbitMQ?". Keduanya bisa melakukan queue dan pub/sub, tapi model penyimpanannya berbeda.

Kafka: log yang dipartisi

Konsekuensinya: di dalam satu group, Kafka bersifat queue (setiap partition dikerjakan satu instance), sedangkan antar-group, Kafka bersifat pub/sub (group billing dan group analytics masing-masing membaca semua event). Jumlah partition adalah batas paralelisme satu group: 6 partition dengan 8 instance berarti 2 instance menganggur.

RabbitMQ: broker dengan exchange dan queue

Kafka (log)RabbitMQ (broker AMQP)
Setelah dibacaTetap tersimpan sampai retention habisDihapus setelah ack
Baca ulang / consumer baru membaca riwayatYa, mundurkan offsetTidak (pesan sudah hilang)
UrutanPer partition (pilih key dengan hati-hati)Per queue, selama satu consumer
RoutingSederhana: topik + keyFleksibel: exchange direct/fanout/topic/headers
Cocok untukEvent stream throughput tinggi, beberapa tim membaca event yang sama, replayJob queue, routing per tipe pesan, pola request/reply

Redis Pub/Sub juga sering disebut, tapi semantiknya "at-most-once": kalau subscriber terputus, "the message is forever lost." Cocok untuk notifikasi yang boleh hilang, bukan untuk pesanan. [6]

Latihan 2 — Kafka, RabbitMQ, consumer group

Jawab tanpa scroll ke atas. Soal yang sama akan muncul lagi, diacak, di review 0026.

4. Kapan tidak perlu

Sinyal yang membenarkan queue: pekerjaan yang lambat (detik, bukan milidetik) atau bergantung pada layanan pihak ketiga yang tidak stabil, dan hasilnya tidak dibutuhkan user saat itu juga; lonjakan beban yang melebihi kapasitas downstream (lesson 0018); atau satu event yang harus diterima beberapa layanan dari tim berbeda. Ukur dulu: berapa p99 bagian yang ingin dipindah, dan seberapa sering layanan itu gagal.

Biaya dan risiko: satu komponen lagi untuk dijalankan, dipantau, dan di-upgrade (cluster Kafka bukan barang kecil); hasil yang tidak langsung konsisten; duplikat dan pesan gagal yang harus ditangani (lesson 0017); dan debugging yang lebih sulit karena tidak ada satu call stack dari request sampai efek.

Alternatif lebih murah:

Latihan lisan — Ucapkan dengan suara keras

Pasang timer dan jawab dengan suara keras, seolah sedang interview. Jangan buka jawaban contoh sebelum selesai.

"Kapan Anda memakai message queue, kapan pub/sub? Kapan Kafka dan kapan RabbitMQ? Dan kapan Anda tidak memakai keduanya?" (60 detik)
Bandingkan dengan jawaban contoh dan checklist-nya

"Asinkron saya pakai kalau pemanggil tidak butuh hasilnya sekarang, misalnya kirim email atau resize gambar, supaya request utama tidak menunggu. Kalau satu pekerjaan cukup dikerjakan satu worker, saya pakai queue dengan competing consumers. Kalau satu event harus diterima beberapa layanan, misalnya OrderPlaced ke email, stok, dan analitik, saya pakai pub/sub supaya masing-masing dapat salinan. Kafka saya pilih kalau butuh log yang bisa dibaca ulang, throughput tinggi, dan urutan per key; paralelismenya dibatasi jumlah partition per consumer group. RabbitMQ saya pilih untuk routing fleksibel lewat exchange dan binding, dengan pesan dihapus setelah ack. Tapi untuk beberapa ratus job per menit, tabel database dengan SELECT FOR UPDATE SKIP LOCKED sering cukup, dan kalau user butuh jawaban sekarang, panggilan sinkron tetap yang paling sederhana."

Checklist: apakah Anda menyebut…

  • Alasan asinkron: pemanggil tidak menunggu pekerjaan yang boleh selesai belakangan
  • Queue = satu pesan ke satu consumer (competing consumers)
  • Pub/sub = setiap subscriber mendapat salinan pesan
  • Kafka: log dengan retention, baca ulang lewat offset, urutan per partition/key
  • RabbitMQ: exchange + binding untuk routing, pesan dihapus setelah ack
  • Membenarkan komponen dengan angka, atau menyebut alternatif lebih murah (tabel DB, panggilan sinkron)

Lulus jika minimal 4 dari 6.

Bacaan lanjutan (opsional, tidak dihitung dalam durasi) Apache Kafka 4.4 docs: Design, bagian "The Consumer" dan "Consumer Position", ±15 menit. Menjelaskan kenapa offset per partition membuat state consumer sangat kecil.

Berikutnya, lesson 0017: pesan bisa hilang atau datang dua kali. At-most-once, at-least-once, exactly-once, dan idempotency key.

Istilah: GLOSSARY.md (bagian "Asinkron") · Indeks: semua lesson System Design

Ada yang belum jelas? Tanyakan ke saya (agent) di terminal, misalnya: "Kenapa Kafka membatasi satu consumer per partition dalam satu group?", "Bandingkan SQS dengan RabbitMQ untuk job queue kecil."

Sumber: [1] Azure Architecture Center: Publisher-Subscriber pattern · [2] Azure Architecture Center: Competing Consumers pattern · [3] Apache Kafka 4.4 docs: Introduction · [4] Apache Kafka 4.4 docs: Design · [5] RabbitMQ: AMQP 0-9-1 Model Explained · [6] Redis docs: Pub/Sub · [7] PostgreSQL docs: SELECT (locking clause)