𝗠𝗲𝗺𝗯𝗮𝗻𝗴𝘂𝗻 𝗦𝗹𝗶𝗱𝗶𝗻𝗴 𝗪𝗶𝗻𝗱𝗼𝘄 𝗥𝗮𝘁𝗲 𝗟𝗶𝗺𝗶𝘁𝗲𝗿 𝗱𝗶 𝗥𝗲𝗱𝗶𝘀

Kuota YouTube API kami mencapai nol sebelum jam 9:00 pagi sebanyak dua kali pada kuartal terakhir. Hal ini menyebabkan feed trending kami menjadi usang di separuh wilayah kami.

Masalahnya bukan pada pertumbuhan trafik. Masalahnya ada pada rate limiter kami.

Kami menggunakan penghitung fixed-window. Ini memungkinkan dua lonjakan besar panggilan API lolos jika terjadi tepat di batas jendela (window boundary). Untuk pipeline global dengan 8 wilayah, tumpang tindih batas ini sering terjadi. Hal ini mengubah kuota harian ketat kami menjadi kebocoran anggaran.

Saya mengganti fixed window dengan sliding window log menggunakan Redis sorted sets.

Berikut cara kerjanya:

  • Gunakan ZADD untuk mencatat permintaan dengan timestamp.
  • Gunakan ZREMRANGEBYSCORE untuk menghapus entri lama di luar jendela.
  • Gunakan ZCARD untuk menghitung dengan tepat berapa banyak permintaan yang tersisa di dalam jendela.
  • Gunakan PEXPIRE untuk membersihkan kunci yang tidak aktif secara otomatis.

Metode ini sangat akurat. Tidak ada batas yang harus dilewati.

Saya mengimplementasikan ini menggunakan skrip Lua di Redis. Ini memastikan seluruh proses pengecekan dan pencatatan bersifat atomik. Jika Anda menjalankan langkah-langkah ini di kode aplikasi, race conditions akan membiarkan permintaan tambahan lolos.

Keputusan teknis utama untuk produksi:

  • Gunakan Redis TIME: Jangan gunakan timestamp dari server aplikasi Anda. Clock skew antar server akan merusak akurasi jendela.
  • Weighted costs: Tidak semua panggilan API sama. Satu panggilan pencarian mungkin memakan 100 unit sementara daftar video hanya 1 unit. Skrip saya menangani ini dengan memasukkan beberapa members per panggilan.
  • Precise Retry-After: Dengan melihat entri tertua dalam sorted set, sistem menghitung dengan tepat kapan kapasitas akan tersedia kembali.
  • Logika fail-safe: Saya menggunakan EVALSHA dengan fallback EVAL. Jika cache skrip Redis terhapus saat restart, aplikasi akan menanganinya dengan baik.

Kompensasinya adalah memori. Setiap permintaan memakan sekitar 100 byte. Untuk kuota harian 10.000 unit, itu hanya sekitar 1 MB memori. Untuk sebagian besar kasus penggunaan, presisi tersebut sepadan dengan biayanya.

Sejak perubahan ini, kuota kami belum pernah habis sekalipun. Job kami berhenti dengan bersih alih-alih terkena error 403.

Jika rate limiter Anda diatur ulang pada angka bulat jam, Anda tidak memiliki batasan. Anda memiliki celah (loophole).

Sumber: https://dev.to/ahmet_gedik778845/building-a-sliding-window-rate-limiter-in-redis-for-a-multi-region-video-api-50ni