Stream adalah struktur data append-only log yang diperkenalkan di Redis 5. Berbeda dari Pub/Sub yang fire-and-forget, Stream MENYIMPAN pesan sehingga consumer yang terlambat tetap bisa membaca riwayat. Setiap entri punya ID unik berformat milidetik-sekuens (contoh 1712345678901-0) yang selalu menaik. XADD menulis, XRANGE membaca rentang, XLEN menghitung.
1. Masalah yang Diselesaikan Stream
Sebelum Stream ada, orang memakai List sebagai antrian dan Pub/Sub sebagai broadcast. Keduanya punya lubang besar:
| Aspek | List (LPUSH/BRPOP) | Pub/Sub | Stream |
|---|---|---|---|
| Pesan disimpan? | Ya, tapi hilang saat dibaca | Tidak โ fire and forget | Ya, tetap ada setelah dibaca |
| Consumer offline saat pesan datang | Pesan menumpuk, aman | Pesan hilang selamanya | Aman, bisa dibaca menyusul |
| Banyak consumer baca pesan sama | Tidak bisa | Bisa | Bisa |
| Pembagian kerja antar consumer | Bisa (rebutan) | Tidak bisa | Bisa via Consumer Group |
| Konfirmasi pemrosesan (ACK) | Tidak ada | Tidak ada | Ada |
| Baca ulang riwayat | Tidak bisa | Tidak bisa | Bisa |
2. Anatomi ID Entri
Setiap entri Stream punya ID unik dengan format <milidetik-unix>-<sekuens>:
1712345678901-0 1712345678901-1 <-- entri kedua di milidetik yang sama 1712345678999-0 <-- milidetik berikutnya
- ID selalu menaik, tidak pernah mundur. Ini yang membuat Stream bisa dibaca berurutan secara andal.
- Tanda
*berarti "biarkan Redis yang membuat ID" โ inilah yang hampir selalu Anda pakai. - Anda boleh menentukan ID sendiri, tetapi wajib lebih besar dari ID terakhir. Berguna saat migrasi data dari sistem lain.
3. Menulis Entri: XADD
# Format: XADD <key> <ID|*> field1 value1 field2 value2 ... XADD pesanan * id_pesanan 1001 user_id 55 total 250000 status baru # => "1712345678901-0" XADD pesanan * id_pesanan 1002 user_id 71 total 89000 status baru # => "1712345678935-0" # Isi entri adalah pasangan field-value, mirip Hash. # Satu Stream boleh berisi entri dengan field yang berbeda-beda.
4. Membatasi Ukuran: MAXLEN dan MINID
Stream tumbuh selamanya kalau tidak dibatasi. Ini penyebab umum Redis kehabisan memori di produksi.
# Simpan KURANG LEBIH 10.000 entri terakhir. # Tanda ~ (perkiraan) jauh lebih murah daripada angka persis, # karena Redis boleh memangkas di batas node radix tree terdekat. XADD pesanan MAXLEN ~ 10000 * id_pesanan 1003 total 45000 # Buang entri yang lebih tua dari ID tertentu (misal: 7 hari lalu) XADD pesanan MINID ~ 1711740000000 * id_pesanan 1004 total 12000 # Memangkas menyusul, tanpa menulis entri baru XTRIM pesanan MAXLEN ~ 10000
~
Tanpa ~, Redis wajib memangkas ke jumlah yang persis, dan itu bisa memblokir server single-thread cukup lama pada Stream besar. Dengan ~, hasil akhirnya "sekitar" jumlah yang Anda minta โ hampir selalu cukup baik, dan jauh lebih aman.
5. Membaca Riwayat: XRANGE dan XREVRANGE
# Baca semua entri. Tanda - berarti ID terkecil, + berarti ID terbesar. XRANGE pesanan - + # Baca 2 entri pertama saja XRANGE pesanan - + COUNT 2 # Baca rentang waktu tertentu (ID boleh hanya bagian milidetiknya) XRANGE pesanan 1712345678901 1712345679999 # Baca dari yang terbaru (untuk menampilkan aktivitas terakhir) XREVRANGE pesanan + - COUNT 5 # Berapa banyak entri sekarang? XLEN pesanan # Informasi struktur stream: panjang, ID pertama & terakhir, jumlah group XINFO STREAM pesanan
6. Membaca Data Baru: XREAD
XREAD membaca entri yang lebih baru dari ID yang Anda sebutkan.
# Baca entri setelah ID tertentu XREAD COUNT 10 STREAMS pesanan 1712345678901 # Tanda $ berarti "hanya entri yang datang SETELAH detik ini" # BLOCK 5000 = tunggu maksimal 5 detik bila belum ada data baru XREAD BLOCK 5000 STREAMS pesanan $ # BLOCK 0 = tunggu selamanya sampai ada entri baru XREAD BLOCK 0 STREAMS pesanan $ # Membaca beberapa stream sekaligus dalam satu perintah XREAD BLOCK 0 STREAMS pesanan pembayaran $ $
$ pada XREAD
$ berarti "abaikan semua yang sudah ada, mulai dari sekarang". Kalau consumer Anda restart dan kembali memakai $, semua pesan yang datang selama proses restart terlewat diam-diam. Untuk pemrosesan yang tidak boleh kehilangan pesan, jangan pakai XREAD dengan $ โ pakai Consumer Group yang dibahas di modul berikutnya.
7. Kapan Memilih Stream, Kapan Memilih Broker Sungguhan
Stream sangat baik, tetapi Redis bukan RabbitMQ atau Kafka. Pilih Stream bila:
- Anda sudah memakai Redis dan tidak ingin menambah komponen infrastruktur baru.
- Volume pesan menengah dan retensi yang dibutuhkan pendek (jam sampai hari, bukan bulan).
- Anda butuh latensi sangat rendah dan pola konsumsi sederhana.
Pindah ke RabbitMQ atau Kafka bila Anda butuh routing rumit (topic exchange, header), retensi panjang berbasis disk, replay skala besar, atau jaminan urutan per-partisi lintas puluhan consumer.