« Tüm yayınlar

Rate Limiting'de Ölçekleme Tuzağı: Doğru Algoritma Seçimi

Yatay ölçeklenen servislerde in-memory rate limit neden aşılır? Token bucket, sliding window, fixed window algoritmalarının production tuzakları ve Redis çözümleri.

Bir servisi tek pod'dan sekiz poda ölçeklediğinizde, her pod kendi RAM'inde ayrı sayaç tuttuğu için 'kullanıcı başına 100 istek/dakika' kuralı fiilen 800 isteğe dönüşebilir. Loglarda hata görünmez, servis çalışıyor gibidir ama downstream sistemler flood olur. Bu klasik hata, sayaçların paylaşılan bir store'a (genellikle Redis) taşınmasını zorunlu kılar ve ardından hangi algoritmanın kullanılacağı sorusunu gündeme getirir.

Fixed window counter en basit yöntemdir ama pencere sınırında iki katına varan burst'lere açıktır. Sliding window log en doğru sonucu verir fakat bellek maliyeti isteklerle doğrusal büyür. Cloudflare'in kullandığı sliding window counter, iki pencereyi ağırlıklı olarak birleştirerek düşük hata payıyla verimli bir orta yol sunar. Stripe'ın da tercih ettiği token bucket ise sabit ortalama hız korurken ani patlamalara (burst) izin verir; GCRA ve redis-cell modülü bu yaklaşımın üretim düzeyinde uygulamalarıdır.

Dağıtık ortamda token bucket'ı GET+SET gibi atomik olmayan işlemlerle kurmak, eşzamanlı isteklerin aynı token'ı iki kez tüketmesine (race condition) yol açar; çözüm Lua script ile tek round-trip'te atomik read-modify-write yapmaktır. Redis'in kendisi tek hata noktası olduğundan, hata anında isteği geçirme (fail-open) ile reddetme (fail-closed) arasında bilinçli bir tercih yapılmalı; pratikte kısa timeout'lu fail-open, alarm ve L7 seviyesinde (Nginx, Envoy) ek bir güvenlik katmanıyla desteklenir.

Bu detaylar mühendisler için önemlidir çünkü rate limiting 'çalışıyor görünen ama aslında koruma sağlamayan' sessiz hata modlarına çok müsaittir; algoritma seçimi, atomiklik garantisi ve hata stratejisi doğru kurgulanmazsa sistem, tam da korumak istediği yükün altında ezilir.

» KaynakDev.to