Kendalikan beban consumer
Panjang antrean, laju kedatangan dan pemrosesan, lag, backpressure, dan pengurangan beban. Kapan antrean menyerap lonjakan dan kapan ia cuma menunda masalah.
Pertanyaan
Antrean ini sedang menyerap lonjakan, atau diam-diam tumbuh tanpa batas? Dan apa yang kita lakukan sebelum jadi tidak berguna?
Setelah baca ini, kamu bisa menghitung berapa lama sebuah antrean kosong, memilih antara menambah worker, membatasi penerimaan, atau membuang beban, dan menyebut tanda kapan masing- masing diperlukan.
Prasyarat dan contoh
Kamu sudah kenal antrean tugas dan ack (M10.01, M10.02), dan hubungan beban kerja dan kapasitas dari M01.
Sebuah layanan notifikasi menerima rata-rata 200 pesan/detik. Ada 6 worker, tiap worker bisa memproses 40 pesan/detik, jadi kapasitas 240/detik. Rasio pemakaian 200/240 = 83%. Pada pukul 12 ada kampanye: kedatangan naik jadi 600/detik selama 10 menit. Selisih 360 pesan/detik × 600 detik = 216.000 pesan menumpuk. Setelah kampanye, kedatangan kembali 200/detik, sisa kapasitas hanya 40/detik. Menguras 216.000 pesan butuh 216.000 / 40 = 5.400 detik, sekitar 90 menit. Notifikasi "OTP" yang berlaku 5 menit ikut antre di belakang semua itu.
Mekanisme
Hitungan dasar. Misal laju kedatangan λ dan laju pemrosesan total μ:
- Jika λ lebih kecil dari μ: antrean pendek dan stabil. Panjangnya hanya mencerminkan variasi acak.
- Jika λ lebih besar dari μ: antrean tumbuh (λ − μ) per detik tanpa batas selama kondisi itu bertahan.
- Waktu menguras setelah lonjakan = backlog / (μ − λ_normal). Perhatikan: semakin tinggi pemakaian normal, semakin lama menguras. Pada 95% pemakaian sisa kapasitas hanya 5%, jadi backlog yang sama butuh 8 kali lebih lama dikuras daripada pada 60% (sisa 40%).
Lag. Ukur lag sebagai umur pesan tertua yang belum diproses, bukan hanya jumlah pesan. Jumlah 10.000 pesan bisa berarti 5 detik atau 5 jam, tergantung laju. Umur langsung dibandingkan dengan target: "OTP harus sampai dalam 30 detik" jadi alarm kalau umur tertua > 20 detik.
Menambah worker menaikkan μ, tapi hanya membantu kalau pembatasnya memang worker. Kalau semua worker menulis ke database yang sudah 90% CPU, menambah worker memindahkan antrean dari broker ke database. Cari dulu komponen yang jenuh (lihat M01.03).
Backpressure. Alih-alih membiarkan antrean tak berbatas, beri batas dan umpan balik ke hulu:
batas antrean = 50.000 pesan
bila penuh → producer ditolak (HTTP 429 / 503) atau diperlambat
Antrean berbatas mengubah "memori habis tengah malam" menjadi "ditolak sekarang dengan pesan jelas". Pemanggil tahu harus menunggu atau mencoba nanti, dan retry-nya harus ber-backoff dengan jitter supaya tidak menyerang serempak.
Pengurangan beban (load shedding). Saat μ tidak mungkin ditaikkan cepat, pilih apa yang dibuang secara sadar:
- Buang yang kedaluwarsa: simpan waktu terbit dan TTL di pesan, worker membuang pesan yang umurnya sudah melewati TTL tanpa memprosesnya.
- Pisahkan prioritas: antrean OTP terpisah dari antrean promosi, dengan worker khusus.
- Gabungkan: seribu update "stok produk X" terbaru cukup diproses sebagai satu.
- Tunda yang boleh telat: promosi diproses saat sepi.
Pembatasan laju konsumsi. Worker perlu batas konkurensi (misalnya 20 request paralel ke layanan email) supaya consumer tidak menjadi penyerang bagi dependensinya sendiri.
Saat rancangan ini gagal
- Antrean tanpa batas. Consumer lambat dua jam, antrean mencapai 40 juta pesan dan broker kehabisan disk. Pesan baru ditolak, pesan lama tetap di sana, dan semua pesan ikut terlambat.
- Memproses pesan basi. Setelah menguras 90 menit, worker mengirim OTP yang sudah kadaluarsa 80 menit lalu. Biaya terbayar, manfaat nol, dan antrean tertahan oleh pekerjaan tak berguna.
- Retry memperbesar badai. Dependensi lambat, worker timeout dan antre ulang pesan. Beban efektif jadi 3 kali lipat karena tiap pesan dicoba 3 kali. Ini bisa menjadi umpan balik yang mengunci sistem dalam keadaan jenuh. Batasi percobaan dan pakai backoff.
- Autoscale terlambat. Scaling dipicu dari CPU worker, padahal worker menunggu I/O dengan CPU 15%. Pemicu yang benar adalah umur pesan tertua atau lag per worker.
- Satu antrean untuk semua. Promosi 2 juta pesan memblokir OTP. Tanpa pemisahan, prioritas hanya ada di slide.
- Ukuran batch salah. Worker mengambil 500 pesan sekaligus tapi lease 30 detik. Pesan di ujung batch kedaluwarsa lease sebelum disentuh dan diproses ganda.
Contoh tandingan: "tambah worker sampai antrean kosong". Kalau pembatasnya tarif API pihak ketiga 100 permintaan/detik, 50 worker tambahan hanya memperbanyak penolakan 429.
Latihan
Layanan resize gambar: kedatangan normal 50 job/detik, 5 worker × 12 job/detik = 60/detik. Saat promosi, kedatangan 150 job/detik selama 4 menit. Job yang lebih tua dari 10 menit tidak berguna lagi.
- Hitung backlog di akhir promosi dan waktu menguras tanpa perubahan.
- Apakah semua job akan berguna? Rancang pengendalian.
- Berapa worker agar backlog habis dalam 10 menit setelah promosi, tanpa membuang job?
Lihat pembahasan
- Selisih 150 − 60 = 90 job/detik × 240 detik = 21.600 job. Sisa kapasitas normal 60 − 50 = 10 job/detik, jadi menguras 21.600 / 10 = 2.160 detik = 36 menit. Job yang masuk di menit pertama baru diproses sekitar menit 40, jauh lewat 10 menit.
- Tidak. Antrean FIFO menguras 10 job/detik lebih cepat dari kedatangan, jadi job yang masuk saat puncak menunggu puluhan menit dan sebagian besar job promosi lewat 10 menit. Rancang: simpan waktu terbit di job dan buang atau lewati job dengan umur > 10 menit; beri batas antrean (misalnya 30.000 job) dan tolak dengan 429 di atasnya agar klien menunda; pisahkan antrean thumbnail interaktif dari antrean batch kalau ada. Hitung juga yang dilewati supaya terlihat di metrik.
- Perlu μ − 50 ≥ 21.600 / 600 detik = 36, jadi μ ≥ 86 job/detik. Dengan 12 job/detik per worker, itu 86 / 12 = 7,2, jadi 8 worker (96/detik). Tapi hanya valid kalau pembatas sebenarnya worker dan bukan storage atau CPU gambar bersama. Cek itu dulu.
Terkait
- M10.02 Tentukan perilaku pengiriman menjelaskan kenapa retry yang tidak dibatasi menggandakan beban.
- M10.04 Pertahankan urutan yang diperlukan memperlihatkan bahwa menambah consumer dibatasi jumlah partisi.
- M01.03 Perkirakan kebutuhan sumber daya membantu mencari komponen yang jenuh lebih dulu.
- Admission control, rate limit, dan circuit breaker dibahas lebih luas di M16.02.
Catatan
- Asumsi: laju konstan per fase dan pesan seragam. Variasi acak dan ukuran pesan yang berbeda membuat antrean lebih panjang dari hitungan ini.
- Hitungan ini model fluida sederhana, bukan teori antrean lengkap. Ia memberi urutan besaran, bukan jaminan kondisi stabil.
- Yang nggak dibahas: autoscaling berbasis prediksi dan penjadwalan adil antar tenant.
- Terakhir ditinjau: 26 Oktober 2026.