Topik wawancara representatif

Wawancara System Design: Bagaimana Cara Anda Merancang Rate Limiter Terdistribusi?

Desain sistemSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Beberapa API berbagi satu cluster dan membutuhkan batasan berdasarkan tenant, pengguna, dan rute saat terjadi lonjakan lalu lintas. Bagaimana Anda merancang limiter tersebut serta menangani konsistensi, kegagalan, dan perubahan kebijakan?

Prompt dan konteks

Pertanyaan ini menguji apakah "N permintaan per menit" dapat diubah menjadi control plane dan data plane yang dapat dioperasikan. Limiter melindungi kapasitas sekaligus menjaga keadilan dan prioritas bisnis; node terdistribusi dan shared state memicu adanya aproksimasi. Bahas kebijakan, algoritma, penyimpanan, respons, fallback, peluncuran (rollout), dan metrik.

Yang diuji oleh pewawancara

Jawaban yang kuat mengklarifikasi dimensi, jendela waktu (window), burst, dan semantik kegagalan sebelum membandingkan token bucket, leaky bucket, fixed window, dan sliding window. Mereka memisahkan distribusi kebijakan dari keputusan saat permintaan datang, menjelaskan atomic counter, hot key, perilaku multi-region, serta kegagalan Redis, dan mengembalikan sinyal Retry-After yang dapat ditindaklanjuti. Mereka juga mendiskusikan peluncuran bayangan (shadow rollout), error budget, dan bypass yang diaudit.

Pertanyaan untuk diklarifikasi

  • Apakah kuncinya adalah API, tenant, pengguna, IP, atau kombinasinya? Apakah pelanggan premium diprioritaskan?
  • Apakah kita mengontrol laju berkelanjutan (sustained rate), ukuran burst, konkurensi, atau beberapa sumber daya sekaligus?
  • Apakah permintaan yang berlebih akan gagal, mengantre, didegradasi, atau menerima sedikit kelebihan kuota (overage)? Apakah konsistensi global diperlukan?
  • Jika limiter tidak tersedia, apakah sistem harus fail-open atau fail-closed? Rute mana saja yang berisiko tinggi?
  • Seberapa sering kebijakan berubah, dan apakah kita memerlukan peluncuran bertahap, audit, rollback, serta efek langsung seketika?

Kerangka jawaban 30 detik

"Saya akan memisahkan kontrol kebijakan dari keputusan saat permintaan tiba. Normalisasi tenant, pengguna, dan rute menjadi sebuah kunci; data plane menjalankan token bucket atomik di Redis Lua serta mengembalikan sisa kuota dan waktu coba lagi. Kebijakan berversi di-cache, di mana cache lokal dapat melakukan penolakan cepat tetapi shared state membuat keputusan akhir. Selama pemadaman singkat pada shared-store, rute berisiko rendah menggunakan anggaran darurat tenant dan menerapkan fail-open; rute berisiko tinggi menerapkan fail-closed dan mengirimkan page. Mode shadow, burn rate, metrik hot-key, dan batas kesalahan regional memandu peluncuran."

Jawaban mendalam langkah demi langkah

Langkah 1: Tentukan kapasitas dan keadilan

Pisahkan laju berkelanjutan, ukuran burst, dan konkurensi. Kuota tenant mencegah satu pelanggan menghabiskan pool global; kuota pengguna mengisolasi kebisingan (noise) di dalam tenant. Rute kritis dapat menerima anggaran khusus. Keadilan adalah kebijakan bisnis, bukan bawaan algoritma yang terjadi secara kebetulan.

Langkah 2: Pilih algoritma

Token bucket mengizinkan burst terkontrol dan cocok untuk API; leaky bucket memuluskan output; sliding window intuitif tetapi membutuhkan lebih banyak state. Saat state dibagi di Redis, gunakan Redis TIME di dalam skrip atomik agar setiap node menggunakan jam yang sama, batasi waktu yang berlalu minimal nol (clamp at zero), serta tentukan pembersihan state dan batas presisi.

Langkah 3: Modelkan kunci dan kebijakan

Normalisasi method, rute, tenant, principal, dan region agar setiap node menghasilkan kunci yang sama. Suatu kebijakan mencakup batas, burst, cakupan, prioritas, versi, waktu efektif, dan pemilik. Kebijakan yang tidak dikenal akan kembali ke baseline yang aman; klien tidak dapat menentukan kuotanya sendiri.

Langkah 4: Buat keputusan bersifat atomik

Satu operasi bersama membaca state, mengisi ulang token, memotong biaya, dan memperbarui TTL. Redis Lua, operasi basis data atomik, atau sidecar dapat digunakan; kuncinya adalah menghindari race condition read-then-write. Kembalikan sisa token, waktu reset, dan versi kebijakan.

Langkah 5: Tangani hot key dan region

Tenant yang populer dapat mengubah satu kunci menjadi hotspot. Shard anggarannya dan gabungkan di koordinator hanya jika batas kelebihan kuota dapat diterima. Sistem multi-region dapat menggunakan kuota regional dan agregasi global secara asinkron; konsistensi global yang ketat mengorbankan ketersediaan dan latensi.

Langkah 6: Rancang kegagalan dan fallback

Pilih fail-open atau fail-closed berdasarkan risiko rute dan tetapkan anggaran darurat lokal. Ketika penyimpanan kebijakan tidak tersedia, gunakan versi terakhir dengan TTL pendek. Pemulihan tidak boleh melepaskan semua akumulasi permintaan sekaligus. Audit setiap bypass dan keputusan yang didegradasi.

Langkah 7: Luncurkan perubahan

Jalankan kebijakan baru dalam mode shadow terlebih dahulu, bandingkan prediksi penolakan, lalu aktifkan berdasarkan tenant atau persentase. Sertakan versi kebijakan dalam log dan siapkan mekanisme rollback. Setiap pengecualian sementara memerlukan pemilik dan masa kedaluwarsa.

Langkah 8: Ukur hasil

Pantau rasio allow/deny, sisa kuota, latensi keputusan p95, hot key, kesalahan penyimpanan, versi kebijakan, banding penolakan salah (false-reject), dan kelebihan beban backend. Hubungkan metrik tersebut dengan 5xx, kedalaman antrean, dan latensi ekor (tail latency); pembatasan yang terlalu longgar gagal melindungi sistem, pembatasan yang terlalu ketat merugikan bisnis.

Pseudocode token-bucket atomik

text
now = redis_time()
state = load(key) or {tokens: burst, at: now}
elapsed = max(0, now - state.at)
state.tokens = min(burst, state.tokens + elapsed * rate)
allowed = state.tokens >= cost
if allowed:
    state.tokens -= cost
state.at = now
save_atomically(key, state, ttl)
return allowed, state.tokens, retry_after(state)

Trade-off dan batasan

PilihanCocok untukBiaya utama
Token bucketAPI dengan traffic burstShared atomic state
Local limiterPerlindungan dengan latensi terendahKuota multi-node tidak presisi
Kuota regionalKetersediaan multi-regionError keadilan global
Fail-closedPembayaran dan autentikasiPemadaman limiter memengaruhi ketersediaan

Rate limiting bukanlah antrean ataupun pengganti untuk perencanaan kapasitas, circuit breaking, atau autentikasi. Antrean cocok untuk permintaan yang dapat menunggu; limiter menolak dengan cepat di batas sumber daya daripada menyembunyikan kelebihan beban sebagai latensi.

Rencana peluncuran dan bukti

Bangun model kebijakan dan data plane token-bucket untuk satu API bervolume tinggi, jalankan mode shadow selama satu hari, lalu aktifkan untuk beberapa tenant. Microsoft Well-Architected memperlakukan throttling sebagai kontrol kelebihan beban aktif; materi DataInterview dan System Design School menekankan pilihan algoritma, shared state, dan Retry-After.

Kriteria keluar tahap pilot

Setelah simulasi untuk lonjakan lalu lintas, kegagalan shared-store, rollback, dan tenant yang padat, target latensi tetap terpenuhi; setiap penolakan yang salah memiliki alasan; anggaran fallback berfungsi; serta kebijakan memiliki pemilik, versi, dan catatan audit.

Cara membuktikan keberhasilannya nyata

Bandingkan kelebihan beban backend, 5xx, latensi p99, rasio penolakan, rasio penolakan salah, dan biaya penyimpanan sebelum dan sesudah penerapan, yang disegmentasikan berdasarkan tenant, rute, dan region. Lakukan normalisasi terhadap kapasitas agar periode lalu lintas rendah alami tidak disalahartikan sebagai keberhasilan.

Kesalahan umum dan pertanyaan lanjutan

Counter lokal di setiap node sudah cukup

Setiap node melepaskan kuotanya sendiri, sehingga klien dapat melebihi batas dengan berpindah-pindah node. Kuantifikasi aproksimasi tersebut atau gunakan shared state/anggaran regional untuk rute kritis.

Hanya menggunakan fixed window

Batas jendela waktu memungkinkan terjadinya double burst singkat. Gunakan token bucket atau sliding window dan jelaskan biaya state serta presisinya.

Mengizinkan semua permintaan lewat saat limiter gagal

Rute berisiko tinggi kehilangan perlindungan terakhirnya. Pilih anggaran darurat dan terapkan fail-open/closed berdasarkan risiko, disertai peringatan paging.

Bagaimana cara menghindari dampak buruk pada tenant premium?

Konfigurasikan kuota dan prioritas tenant, pisahkan pool bersama dan pool bergaransi, serta berikan masa kedaluwarsa dan jejak audit pada setiap pengecualian.

Bagaimana seharusnya klien mencoba lagi?

Patuhi Retry-After, gunakan backoff dengan jitter, dan jangan pernah mengulang 429 tanpa henti. Percobaan ulang otomatis memerlukan permintaan yang idempoten.

Bagaimana cara melakukan canary untuk kebijakan baru?

Kalkulasikan dalam mode shadow, aktifkan berdasarkan tenant atau persentase, bandingkan penolakan, konversi, dan beban backend, serta buat versi pada kebijakan untuk kemudahan rollback.

Sumber publik

Pertanyaan terkait

Alat wawancara terkait

Gunakan Jawab untuk jawaban desain sistem

Perjelas persyaratan terlebih dahulu, lalu lanjutkan dengan skala, arsitektur, pilihan komponen, dan trade-off.

Lihat alat