Kodeloka
  1. Kodeloka
  2. Kelas Redis
  3. Materi

Advanced ยท Modul 12 dari 21

Redis Streams - Log Append-Only untuk Event

Struktur data Stream sebagai log kejadian yang tahan lama, perbedaannya dengan List dan Pub/Sub, serta perintah XADD, XRANGE, dan XLEN.

๐Ÿ“Œ Ringkasan Eksekutif Modul:
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:

AspekList (LPUSH/BRPOP)Pub/SubStream
Pesan disimpan?Ya, tapi hilang saat dibacaTidak โ€” fire and forgetYa, tetap ada setelah dibaca
Consumer offline saat pesan datangPesan menumpuk, amanPesan hilang selamanyaAman, bisa dibaca menyusul
Banyak consumer baca pesan samaTidak bisaBisaBisa
Pembagian kerja antar consumerBisa (rebutan)Tidak bisaBisa via Consumer Group
Konfirmasi pemrosesan (ACK)Tidak adaTidak adaAda
Baca ulang riwayatTidak bisaTidak bisaBisa
๐Ÿ’ก Analogi: Pub/Sub itu seperti siaran radio โ€” kalau Anda tidak menyalakan radio saat itu, acaranya lewat begitu saja. Stream itu seperti rekaman podcast โ€” Anda bisa mendengarkannya kapan saja, mengulang, bahkan membaginya ke beberapa orang untuk didengarkan bergantian.

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

redis-cli
# 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
โš ๏ธ Selalu pakai tanda ~

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 $ $
๐Ÿšซ Jebakan $ 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.