RabbitMQ Streams membawa kemampuan log append-only bergaya Kafka ke dalam broker AMQP. Di episode ini kalian memahami konsumsi non-destruktif dengan offset, multiple consumer groups, replay pesan, retention policy dan stream filtering, serta kapan memakai stream dibandingkan queue.

Sejauh ini, semua pola yang kita pelajari bersifat consumptive: begitu pesan di-ack, pesan itu hilang dari queue selamanya. Tapi ada kategori workload yang justru ingin menyimpan aliran event dan membacanya berkali-kali — event sourcing, audit log, dan analitik real-time. Untuk kebutuhan inilah RabbitMQ Streams lahir pada versi 3.9.
Stream berbeda fundamental dari queue: data disimpan sebagai log append-only yang tidak dihapus setelah dibaca. Consumer menandai posisinya dengan offset, bisa mundur (replay), dan beberapa consumer group bisa membaca log yang sama secara independen. Semantiknya mirip Kafka, tapi tetap hidup di dalam RabbitMQ yang sama.
Episode ini menjelaskan cara kerja stream, fitur utamanya seperti offset tracking dan retention, protokol khususnya yang memakai koneksi terpisah, serta panduan kapan memakai stream dan kapan tetap memakai queue.
Stream adalah struktur append-only: pesan baru selalu ditambahkan di ujung log, dan konsumsi tidak menghapus data. Ini kebalikan dari queue, di mana pesan dihapus setelah di-ack. Karena itu, stream cocok untuk workload yang membutuhkan pembacaan ulang.
Perbedaan mendasar lainnya: stream di-replikasi (mirip quorum queue) dan dioptimalkan untuk throughput tinggi serta penulisan disk yang efisien.
Stream dideklarasikan lewat plugin rabbitmq_stream dengan tipe queue stream:
rabbitmqadmin declare queue name=events.stream \
arguments='{"x-queue-type":"stream"}'Setelah plugin stream aktif, client AMQP bisa publish dan consume stream seperti queue biasa, dengan pembeda bahwa konsumsi dilakukan dengan basic_consume pada posisi tertentu.
Satu perbedaan penting yang harus diingat: stream tidak mendukung fitur-fitur queue seperti TTL, dead letter exchange, dan priority. Jika kalian membutuhkan fitur-fitur itu, gunakan quorum queue. Stream mengorbankan fitur-fitur tersebut demi kecepatan dan kapasitas penyimpanan yang besar.
Setiap consumer stream menyimpan posisi baca (offset) sendiri-sendiri, atau bersama dalam consumer group. Dengan group, beberapa consumer berbagi beban baca dengan offset yang disinkronkan; tanpa group, setiap consumer membaca seluruh log dari posisi masing-masing. Ini memungkinkan dua kelompok aplikasi membaca event yang sama secara independen.
Karena log tidak dihapus saat dibaca, consumer bisa memulai ulang dari offset mana pun — termasuk dari awal log. Retention policy membatasi berapa lama data disimpan:
rabbitmqadmin declare queue name=audit.stream \
arguments='{"x-queue-type":"stream","x-max-age":"7D","x-max-length-bytes":"20GB"}'Argumen x-max-age=7D menahan data stream selama 7 hari, dan x-max-length-bytes membatasi total ukuran — lebih lama dari itu data lama dihapus.
Offset dicommit oleh consumer secara otomatis dalam interval tertentu, atau secara manual lewat API client. Consumer yang baru bergabung ke sebuah consumer group memulai dari offset yang disimpan terakhir — atau dari awal log jika belum ada offset tersimpan, tergantung konfigurasi. Pahami perilaku ini saat men-deploy ulang consumer: pastikan offset awal sesuai dengan kebutuhan replay aplikasi kalian.
RabbitMQ 3.13+ mendukung stream filtering: consumer bisa mendaftarkan filter saat subscribe, sehingga hanya pesan yang cocok yang dikirim — menghemat bandwidth saat hanya sebagian event yang dibutuhkan. Filter diterapkan di sisi broker sebelum pesan dikirim.
Satu stream yang sangat besar bisa menjadi bottleneck karena semua data melalui satu partition. Super stream (3.13+) memecah satu stream logis menjadi beberapa stream fisik yang dipartisi berdasarkan kunci. Publisher memilih partition lewat hash pada routing key, sehingga beban menyebar merata dan tiap partition bisa diskalakan independen. Super stream adalah jawaban ketika satu stream tidak lagi cukup untuk throughput yang dibutuhkan.
Stream adalah pilihan tepat untuk: event sourcing (riwayat lengkap perubahan state), audit logs (data harus tersedia untuk investigasi), time-series data, dan fan-out dengan replay ke banyak consumer yang butuh membaca event yang sama. Karena throughput-nya tinggi, stream juga cocok untuk pipeline analitik.
Panduan memilih:
Jika kalian butuh dua-duanya, kombinasi keduanya di RabbitMQ yang sama adalah sah: gunakan queue untuk command dan stream untuk event.
Stream bisa diakses lewat AMQP biasa (mudah, satu koneksi untuk semua), atau lewat protokol stream native (rabbitmq_stream di port 5552) yang menawarkan performa terbaik dengan koneksi khusus. Client resmi stream tersedia untuk Java, Go, .NET, dan Rust; client AMQP untuk bahasa lain tetap bisa memakai stream.
ss -tlnp | grep 5552Perintah ss -tlnp memverifikasi port 5552 (protokol stream native) sedang mendengarkan setelah plugin aktif.
Konsumsi stream yang tertinggal jauh di belakang menambah beban disk dan jaringan. Pantau posisi consumer relatif terhadap ujung log:
rabbitmqctl list_streams name consumer_countlist_streams menampilkan setiap stream beserta jumlah consumer yang aktif. Jika selisih offset consumer dengan ujung log terus membesar — bisa dilihat di halaman stream pada Management UI — berarti consumer tidak mampu mengimbangi laju penulisan. Solusinya: tambah partition (super stream), perbesar paralelisme consumer, atau turunkan retention.
Untuk throughput maksimum: pakai protokol stream native, atur batch publish yang lebih besar, dan naikkan ukuran frame. Pantau metrik stream di Management UI — konsumsi stream dengan offset lambat akan menambah beban disk, jadi sesuaikan retention dengan kebutuhan replay.
Warning
Jangan gunakan stream untuk workload yang membutuhkan pengiriman sekali-saja (at-least-once dengan ack). Stream mengutamakan penyimpanan dan replay, bukan semantik queue — untuk itu tetap pakai quorum queue.
Di episode 21 ini kalian sudah memahami stream sebagai log append-only bergaya Kafka, mengelola offset dan consumer groups, melakukan replay dan retention, memakai stream filtering, serta memilih antara stream dan queue berdasarkan workload.
Inti yang harus dibawa pulang:
x-max-age dan x-max-length-bytes.Di episode 22 selanjutnya kita akan mengoptimalkan performance tuning — batching dan async publish, tuning prefetch, pemilihan tipe queue, lazy queues, hingga tuning level sistem seperti Erlang VM, file descriptors, dan disk I/O. Ini yang membedakan broker yang berjalan lancar dan yang tersendat di bawah beban!