Belajar NATS - JetStream Streams
Episode 8 of 23

Belajar NATS - JetStream Streams

Episode ini membedah konfigurasi stream secara lengkap: subjects, retention dengan mode Limits, Interest, dan WorkQueue, storage file atau memory, max_age dan max_bytes, replikasi, serta stream sourcing, mirroring, dan dedupe window untuk exactly-once publish.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Pendahuluan

Episode 7 memberi kalian kenalan pertama dengan JetStream. Episode 8 ini masuk lebih dalam: bagaimana mengkonfigurasi stream dengan presisi. Di sinilah keputusan arsitektural diambil — berapa lama pesan disimpan, bagaimana pesan dihapus, apakah disimpan di file atau memory, dan berapa banyak salinan yang dimiliki.

Pilihan yang salah di episode ini bisa berujung pada kehilangan data atau pemborosan disk di produksi. Mari kita bedah setiap bagian konfigurasi stream, lalu lanjut ke sourcing, mirroring, dan dedupe window.

Konfigurasi Dasar Stream

Mendefinisikan Subjects Stream

Setiap stream harus punya nama dan daftar subject yang ditangkap. Sebuah stream bisa menangkap banyak subject sekaligus memakai wildcard:

Membuat stream dengan beberapa subject
nats stream add ORDERS --subjects "orders.>" --subjects "payments.charged"

Perintah nats stream add ORDERS --subjects "orders.>" membuat stream ORDERS yang menyimpan semua pesan di bawah orders.> dan payments.charged. Satu subject hanya bisa ditangkap oleh satu stream dalam satu akun — NATS menolak jika ada tumpang tindih antar stream.

Semua Opsi dalam Satu Perintah

Untuk menghindari mode interaktif, semua opsi bisa dilewatkan sekaligus:

Stream dengan opsi lengkap
nats stream add ORDERS \
  --subjects "orders.>" \
  --retention limits \
  --storage file \
  --max-age 30d \
  --max-bytes 1G \
  --replicas 3

Skema --max-age 30d menunjukkan pesan bertahan maksimal 30 hari, --max-bytes 1G membatasi total ukuran, dan --replicas 3 menjaga tiga salinan. Ketiga keputusan ini adalah inti dari manajemen siklus hidup data.

Retention Policy

Limits: Simpan Sampai Penuh

Limits adalah mode default: pesan disimpan sampai melampaui batas usia atau ukuran, lalu dihapus paling lama. Ini cocok untuk event log dengan horizon waktu tertentu, misalnya menyimpan event pesanan selama 30 hari.

Interest: Simpan Selama Ada Subscriber

Interest menyimpan pesan selama masih ada consumer yang tertarik membacanya. Ketika semua consumer sudah memproses pesan dan tidak ada yang menunggu, pesan dihapus. Cocok untuk workload di mana pesan tidak perlu disimpan setelah diproses semua pihak.

WorkQueue: Satu Pesan Sekali Pakai

WorkQueue dirancang untuk job queue: setiap pesan hanya boleh dibaca oleh satu consumer. Begitu pesan diack, ia langsung dihapus dari stream. Tidak ada replay, tidak ada broadcast.

ModePesan dihapus ketikaPenggunaan umum
LimitsMelampaui batas usia/ukuranEvent log berdurasi
InterestSemua consumer selesai membacaEvent untuk banyak service
WorkQueueSatu consumer mengackJob queue

Pola WorkQueue ini adalah dasar dari work queue yang akan kita bangun secara penuh di episode 11.

Storage dan Batasan Resource

File atau Memory

Opsi storage menentukan media penyimpanan:

  • File: data ditulis ke disk, bertahan dari restart server.
  • Memory: data di RAM, sangat cepat tapi hilang saat server mati.
Stream berbasis memory
nats stream add CACHE --subjects "cache.>" --storage memory --retention limits

nats stream add CACHE --subjects "cache.>" --storage memory cocok untuk data sementara seperti cache. Untuk semua data yang tidak boleh hilang, selalu pilih storage file.

Membatasi Usia dan Ukuran

Dua batasan paling umum:

Blok konfigurasi batasan
subjects: ["orders.>"]
retention: limits
storage: file
max_age: 7d
max_bytes: 2GiB
max_msgs: 1000000
discard: old

Blok max_age: 7d menghapus pesan yang lebih tua dari 7 hari, dan discard: old menentukan bahwa saat penuh, pesan terlama dihapus dulu. Kombinasi batas ini mencegah disk terisi tanpa batas.

Warning

Tentukan max_bytes sejak awal. Stream tanpa batas ukuran akan terus tumbuh sampai memenuhi disk dan membuat server crash. nats stream report bisa menunjukkan stream mana yang sudah mendekati batas.

Replikasi dengan Replicas

Tiga Salinan untuk Ketahanan

Field replicas menentukan berapa salinan stream yang disimpan di server berbeda dalam satu cluster. Nilai 1 untuk single-node, 3 untuk cluster yang toleran kehilangan satu node, 5 untuk toleran dua node.

Menambah replicas pada stream
nats stream edit ORDERS --replicas 3

Perintah nats stream edit ORDERS --replicas 3 mengubah jumlah salinan stream yang sudah ada. Setiap salinan disinkronkan lewat konsensus Raft — topik yang akan kita bahas di episode 14. Aturan praktis: replicas harus selalu lebih kecil dari jumlah node cluster.

Sourcing dan Mirroring

Stream Sourcing Antar Subject

Sourcing memungkinkan sebuah stream menarik pesan dari subject yang sumbernya justru berasal dari stream lain:

Stream dengan sumber stream lain
nats stream add ORDERS_ANALYTICS --subjects "analytics.>" --sources ORDERS

--sources ORDERS membuat ORDERS_ANALYTICS menyalin setiap pesan yang masuk ke stream ORDERS. Ini pola populer untuk membentuk data mart: stream utama tetap bersih, stream turunan dibuat untuk keperluan analytics tanpa mengganggu alur utama.

Mirroring Antar Cluster atau Region

Mirroring menyalin seluruh isi sebuah stream dari stream lain — biasanya di cluster atau region yang berbeda — untuk keperluan disaster recovery:

Konfigurasi mirroring
name: ORDERS_DR
mirror:
  name: ORDERS
  external:
    api: nats://dr-cluster:4222

Blok mirror di atas membuat stream ORDERS_DR mencerminkan stream ORDERS yang berada di cluster disaster recovery. Ini adalah fondasi strategi DR lintas region yang akan kita bangun di episode 21.

Dedupe Window dan Exactly-Once Publish

Mencegah Pesan Ganda

JetStream menyediakan dedupe window: setiap publisher bisa menyertakan header Nats-Msg-Id. Jika pesan dengan ID yang sama masuk lagi dalam jendela waktu dedupe, pesan ganda ditolak. Ini langkah pertama menuju exactly-once publish.

Publish dengan ID dedupe
nats pub orders.created "pesanan-1" --id order-2026-08-10-001

nats pub orders.created "pesanan-1" --id order-2026-08-10-001 memberi identitas unik pada pesan. Jika client kehilangan ack lalu mengirim ulang pesan dengan ID yang sama, JetStream mendeteksi duplikat dan mengembalikan ack tanpa menyimpan pesan kedua kali.

Jendela Waktu Dedupe

Jendela default dedupe adalah 2 menit, bisa disesuaikan pada stream:

Mengatur dedupe window
nats stream edit ORDERS --dedupe-window 5m

--dedupe-window 5m memperpanjang jendela menjadi 5 menit. Dedupe hanya menjamin publish tidak ganda; untuk pemrosesan yang idempotent, kalian masih perlu mekanisme tambahan yang akan dibahas di episode 11.

Penutup

Episode 8 membekali kalian kendali penuh atas stream: mendefinisikan subjects, memilih retention Limits, Interest, atau WorkQueue, menentukan storage file atau memory, membatasi max_age dan max_bytes, mengatur replikasi, serta memahami sourcing, mirroring, dan dedupe window untuk exactly-once publish.

Inti yang harus dibawa pulang:

  • Stream menangkap subject dengan opsi retention, storage, dan batasan resource.
  • Limits untuk event log berdurasi, Interest untuk banyak consumer, WorkQueue untuk job queue.
  • Storage file untuk data yang harus bertahan, memory untuk data sementara.
  • max_bytes wajib ditentukan agar disk tidak penuh.
  • replicas menentukan jumlah salinan; harus lebih kecil dari jumlah node.
  • Sourcing menyalin pesan antar stream; mirroring untuk DR lintas region.
  • Dedupe window dengan Nats-Msg-Id mencegah publish ganda.

Di episode 9 selanjutnya kita akan membahas JetStream consumers — perbedaan pull dan push consumer, durable versus ephemeral, semantik ack, nack, ackWait, dan max delivery untuk redelivery, serta deliver_policy dan replay untuk menentukan dari mana consumer mulai membaca. Di sinilah cara membaca stream diatur presisi.

Belajar NATS - JetStream Streams | Belajar NATS