· kaynak dev.to (home feed)
Valkey 9.2, INCREX komutunu ekliyor: INCR ve EXPIRE ile rate limit deseni için tek atomik komut
Valkey 9.2.0-rc1 üzerinde yapılan pratik bir test, yeni INCREX komutunun artırma işlemini ve süre sonunu atomik olarak birleştirdiğini gösteriyor; böylece rate limit sayaçlarını TTL'siz bırakan çökme penceresi kapanıyor.

Docker Hub'ta şu anda 9.2.0-rc1 release candidate olarak sunulan Valkey 9.2, INCREX komutunu tanıtıyor; bu komut bir anahtarın değerini artırıyor ve time-to-live süresini tek bir atomik çağrıda atıyor. dev.to'da yayımlanan uygulamalı teste göre komut, rate limiter'ların ve kota sayaçlarının büyük bir kısmının temelini oluşturan iki adımlı INCR artı EXPIRE kalıbını hedefliyor ve en önemli faydası hızdan çok doğruluk olduğu ortaya çıkıyor: iki çağrı arasında her zaman var olan bir hata durumunu ortadan kaldırıyor.
Komut ne yapıyor
Söz dizimi şöyle: INCREX key [NX|XX] [EX seconds|PX ms|EXAT ts|PXAT ts] [BYINT n|BYFLOAT n]; BYINT veya BYFLOAT ifadesi verilmezse birer birer artırılır. Sunucunun kendi komut dokümantasyonu INCREX'i 9.2.0'dan itibaren kullanılabilir olarak işaretliyor ve dev.to yazarı, önceki kararlı 9.1.2 image'ında komutun tamamen bulunmadığını doğruladı. Operasyonel bir pürüz: INFO server çıktısı, candidate build'leri -rc1 eki olmadan düz 9.2.0 olarak raporluyor; yani yalnızca sunucuyu sorgulayarak bir release candidate'i final build'den ayırmanın yolu yok.
Test kurulumunda iki container image'ı aynı ana makinede çalıştırıldı ve localhost TCP üzerinden redis-py 8.1.0 kullanan bir Python betiğiyle yönetildi.
Hızlanma gerçekte nereden geliyor
Kıyaslama, birbirinden farklı anahtarlar üzerinde 2.000 işlemi, her biri üç kez çalıştırarak karşılaştırdı. Geleneksel kalıp — bloklayan bir INCR ve sayaç 1'i gösterdiğinde koşullu bir EXPIRE — işlem başına ortalama yaklaşık 0,46 ile 0,57 ms sürerken, INCREX için bu değer 0,26 ile 0,29 ms oldu; tekrarlanabilir bir 1,6x ile 2x iyileşme.
dev.to yazarı ardından eski kalıbı pipeline'a soktu, INCR ve EXPIRE'ı tek bir batch olarak gönderdi ve fark 9 ile 21 yüzde arasına düştü. Yani göz önündeki büyük rakam, sunucu tarafında daha hızlı bir komutu değil, ikinci bir ağ gidiş-dönüşünün maliyetini yansıtıyor. Yazarın gözlemi, bu kodu gerçekten pipeline'a sokan ekip sayısının az olduğu; çünkü anahtarı yalnızca ilk artırmada sona erdiren koşullu mantık, batch'lemeyi hantallaştırıyor ve gerçek dağıtımların çoğu yine tam tasarrufu görecektir.
Ortadan kaldırdığı hata durumu
Geçiş yapmak için daha güçlü argüman, iki çağrı arasındaki penceredir. Bir istek zaman aşımına uğrarsa, süreç ölürse ya da bir deploy INCR yerleştikten sonra ama EXPIRE gönderilmeden önce süreci öldürürse, sayaç süresiz olarak var olur ve asla sıfırlanmaz. dev.to yazısındaki simülasyon, ilk komut başarıyla tamamlandıktan hemen sonra çökme olasılığı yüzde 2 olacak şekilde 500 istek çalıştırdı: eski kalıp 11 anahtarı kalıcı olarak TTL'siz bırakırken, INCREX sıfır anahtar bıraktı.
Tek bir komut olduğunda içinde çökebilecek bir ara durum yoktur: ya henüz hiçbir şey olmamıştır, ya da yeni değer ve TTL'si zaten atanmıştır. 20 iş parçacığının paylaşılan tek bir anahtar üzerinde 100'er artırma yaptığı ayrı bir çekişme testi tam olarak 2.000 sonucuna ulaştı ve ilk çağıranın atadığı TTL'yi diğer 1.999 çağrı bozulmadan korudu; bu da kayıp güncelleme olmadığını doğruluyor.
Geçişteki tuzaklar
İki davranış yazarı şaşırttı. Birincisi, INCREX'in NX ve XX bayrakları SET'in kuralını izliyor ve anahtarın var olup olmadığını test ediyor; EXPIRE'ın TTL'nin zaten mevcut olup olmadığını test etme kuralını değil. Zaten var olan bir anahtar üzerinde NX ile INCREX çağırmak işlemin tamamını reddediyor: artırma atlanıyor ve yanıtın ikinci öğesi, yani fiilen uygulanan miktar, 0 okunuyor. EXPIRE'ın NX'inin "zaten çalışan bir pencereyi asla sıfırlama" anlamına geldiğine bel bağlayan kod, INCREX'e hiçbir koşul olmadan geçirilmeli; çünkü komut, süre ifadesi verilmediğinde mevcut TTL'ye dokunmuyor.
İkincisi, taşma davranışı INCR'den farklı. INCR'yi signed 64-bit sınırının ötesine itmek açık bir hata yükseltiyor, ama INCREX asla hata fırlatmıyor: değer yalnızca artmayı bırakıyor ve uygulanan miktar 0 dönüyor. INCR'yi exception handling'e sarmalayan bir çağıran, INCREX altında takılmış bir sayacı sessizce gözden kaçırır ve her çağrıda yanıtın ikinci öğesini incelemek zorundadır. Tip hataları INCR ile birebir aynı ve tek bir çağrıda BYINT ile BYFLOAT'ı birleştirmek söz dizimi hatasıdır.
Neden önemli
Süre sonu ile artırma, backend altyapısında en yaygın şekilde kopyalanan desenlerden biri ve TTL'siz mahsur kalan her sayaç hem kalıcı bir bellek sızıntısı hem de bir rate limiter'da potansiyel olarak sonsuza dek kısıtlanmış bir kullanıcı demektir. INCREX bu hata sınıfını disiplinle değil, yapısı gereği çözüyor. Release candidate statüsü, SET tarzı bayrak semantiği ve sessiz taşma davranışı gibi uyarılar, geçişin özen istediği anlamına geliyor. Ama Valkey tabanlı rate limiter veya kota sayacı çalıştıran herkes için bu, 9.2 sürümündeki en pratik faydalı değişiklik.
- #valkey
- #rate-limiting
- #redis
- #databases
- #open-source