· kaynak dev.to (home feed)
Valkey 9.1 hash field TTL, kendi dokümantasyonundaki kullanıcı başına token deseninde bellek kullanımını üçe katlıyor
dev.to üzerinde yayınlanan bir benchmark, tek bir field TTL'nin hash'i listpack'ten hashtable kodlamasına geçirerek Valkey'in kendi HSETEX örneklerinde gösterilen öğe başına bir hash token deseninde bellek kullanımını üçe katladığını ortaya koydu.

dev.to'da yayınlanan bir benchmark, Valkey 9.1'in hash field TTL özelliğinin, Valkey'in kendi dokümantasyonunun özelliği tanıtmak için kullandığı desenle bellek kullanımını kabaca üçe katladığını bildiriyor. Yazar, Docker üzerinde Valkey 9.1.2'yi 20.000 key ile test edip INFO memory üzerinden ölçüm yaparak, hash tabanlı desenin yaklaşık 5,2 MB tükettiğini, eşdeğer düz string key'lerin ise kabaca 1,7 MB kullandığını buldu.
Neler ölçüldü
Valkey 9.0, tüm key yerine tekil hash field'larına TTL uygulanmasını getiridi ve 9.1, bir field ile son kullanma süresini tek turda ayarlayan HSETEX'i ekledi. Valkey'in blogu bunu kullanıcı başına bir auth token ile örneklendiriyor: HSETEX user:123 EX 900 FIELDS 1 auth_token, ardından token değeri. SET ve EX kullanan düz bir string key'in doğrudan yerine geçecek şekilde okunduğunda bu düzenli bir yükseltme gibi görünüyor.
dev.to yazarı, alexgeorguv17 takma adıyla yazan kişi, konteynerin açık portundan redis-py 8.1.0 ile sunucuyu sürerek 20.000 süresi dolan öğe için üç düzeni karşılaştırdı. HSETEX ile field TTL'si ayarlanmış, öğe başına bir hash, hashtable kodlamasında 5.226.560 bayt, yani key başına yaklaşık 261 bayt kullandı. TTL'siz öğe başına bir hash, listpack kodlamasında 1.754.720 bayt, key başına yaklaşık 88 bayt kullandı. Düz bir string key artı EXPIRE ise 1.733.680 bayt, key başına yaklaşık 87 bayt kullandı. Başka bir deyişle, dokümante edilen hash deseni, kendisine karşı konumlandırıldığı string deseninin üç katı bellek maliyetine sahip ve üstüne hash'in kendi yönetim yükünü de taşıyor.
Nedeni bir kodlama değişimi
Yazar, OBJECT ENCODING kullanarak, tek bir field TTL ayarlamanın bile — kaç field olduğu fark etmeksizin — hash'i listpack'ten hashtable'a geçirdiğini doğruladı. Varsayılan 512 değerindeki hash-max-listpack-entries fark yaratmadı. Ekstra baytların neredeyse tamamından, son kullanma takibinin kendisi değil kodlama dönüşümü sorumlu. Gönderiye göre bu bilinen bir eksiklik: Valkey issue #2618 bu davranışı tanımlıyor ve küçük hash'ler için son kullanma verisini listpack içinde saklamayı öneriyor, ancak 9.1.2 itibarıyla bu değişiklik henüz gelmiş değil.
Özelliğin karşılığını verdiği düzen
Gönderi, özelliğin için tasarlandığı görünen yapıyı da test etti: her biri kendi TTL'sini taşıyan 20.000 field içeren tek bir hash. TTL'li ve TTL'siz varyantların ikisi de hashtable kodlamasındaydı, çünkü 20.000 field listpack sınırını aşıyor. Fark field başına 23,44 bayt oldu; yazar bunun Valkey geliştiricilerinin issue #2618'de verdiği 16 ila 29 bayt aralığıyla örtüştüğüne dikkat çekiyor. Sunulan çıkarım şu: maliyet TTL takibinden değil kodlamadan kaynaklanıyor. Bir hash zaten hashtable'ta yaşayacak kadar büyükse field başına TTL'ler neredeyse bedava, küçük bir hash üzerindeki tek bir TTL ise listpack'ten tamamen feragat ediyor.
Testlerden çıkan diğer bulgular
- Okumalarda hiçbir ceza yok. 5.000 field'lı bir hash üzerinde HGET throughput'u, her field'da TTL olsun ya da olmasın istatistiksel olarak ayırt edilemezdi; çağrı başına kabaca 205 mikrosaniye ile saniyede yaklaşık 4.885 ila 4.889 ops, ancak yazar gecikmenin ağırlıklı olarak Docker'ın port eşlemeli ağ turundan kaynaklandığı konusunda uyarıyor.
- Eşzamanlılık hiçbir şeyi değiştirmedi. Ona pipelanmış thread, thread başına hash'ler, paylaşılan tek hash ve bağımsız string key'lerde örtüşen throughput değerleri elde etti — saniyede kabaca 62.000 ila 69.000 ops — çünkü Valkey komutları istemci sayısından bağımsız olarak tek bir thread üzerinde yürütüyor.
- Field TTL'leri, arka plan kaydından sonra konteynerin tamamen yeniden başlatılmasından sonra da varlığını sürdürdü ve sıfırlanmak yerine geri saymaya devam etti.
- Son kullanma zamanında çalıştı: iki saniyelik TTL verilen 2.000 field'ın tümü tek bir 200 milisaniyelik yoklama penceresi içinde kayboldu; INFO stats, expired_fields'ı 2000 ve expire_cycle_cpu_milliseconds'ı 3 olarak bildirdi. expired_subkeys diye bir istatistik yok.
- Bilinmesi gereken hata yolları: HEXPIRE, string key'lere karşı WRONGTYPE döndürüyor, negatif son kullanma sürelerini ve uyumsuz NX, XX, GT ve LT kombinasyonlarını reddediyor, eksik field ya da hash'ler için -2 döndürüyor. TTL'si olmayan bir field üzerinde GT ile HEXPIRE, 0 döndüren dokümante edilmiş bir no-op.
Neden önemli
Field TTL'ler gerçekten yararlı bir yetenek, ancak yayınlanan örnek operatörleri en pahalı oldukları düzene davet ediyor. Valkey'in HSETEX dokümantasyonundaki kullanıcı başına token desenini benimseyenler, önceki string key tasarımlarının kabaca üç katı belleği — herhangi bir hata olmadan, okuma yolunda bir yavaşlama sinyali olmadan — sessizce ödüyor olabilirler. Issue #2618'in listpack desteği gelene kadar ekipler hash'lerini bilinçli boyutlandırmalı: süresi dolan çok sayıda field'ı paylaşılan, hashtable ölçeğinde hash'lerde toplamalı, tek süresi dolan değerleri düz string key olarak tutmalı ve kompakt temsilini sessizce yitiren hash'leri yakalamak için expired_fields istatistiğiyle birlikte OBJECT ENCODING'i izlemeliler.
- #valkey
- #memory-management
- #hash-ttl
- #benchmarking
- #key-value-store