Redis Ziplist ile Memory Optimizasyonu

1. Redis Ziplist Kavramı Nedir ve Ne işe Yarar?

   Caching mekanizmalarında tuttuğumuz datalar memoryde tutulmaktadır. Redis gibi ileri cache mekanizmalarının kullanılmasıyla birlikte memoryde cachlenmiş olarak tuttuğumuz dataların hem boyutları hem yapıları komplekslikleri hem de önem dereceleri oldukça arttı. Dolayısıyla bu gibi toollarda performans yönetimi önceki zamanlara göre daha da önem kazandı. Redis ile kullandığımız memory miktarını azaltarak,data persistency için shapshot alma ve shopshotu yükleme sürelerini aynı şekilde AOF fileini yükleme ve yazma sürelerini azaltmayı ve hatta rediste daha fazla data tutmayı bile sağlayabiliriz. Rediste kullanılan memory miktarını azaltmanın farklı yaklaşımları ve yöntemleri var. Ben bu yazıda buna ilişkin olan ziplist kavramı üzerinde duracağım.

  Redis çoğu caching mekanızmasından farklı olarak bize datamızı tutabilmemiz için 5 farklı veri yapısı sunar. Bunlar string, list, hash, set ve zsettir. Biz verilerimizi uygun veri yapısına koyarak rediste tutarız. Hatta çoğunlukla verilerimizi boyut küçültebilmek için encode ederek redise atarız.  Ancak redis bizim encode edilmiş ya da edilmemiş datalarımızı arkada bir de kendisi tekrar encode eder. Bu encode etme işlemi verinin boyutunu küçülterek memoryde daha az yer tutmasını sağlar. Buraya kadar herşey normal güzel ve ideal. Redis veriyi alıyor serialize ediyor ve daha az boyutlu bir şekilde memoryde tutuyor. Ancak herşey göründüğü kadar dikensiz gül bahçesi değil.

   Redis tuttuğu bir objemizi encode ederken doğal olarak CPU tüketiyor ve biz bu veriyi okumak isterken de decode ederek CPU harcıyor. Bu 50 elemanlı bir listten ya da zsetten bir eleman okurken dahi yapılması gereken bir işlem. Yani aslında ortada bir Memory – CPU trade-off’u var diyebiliriz. Redis de bu süreci olabildiğince şeffaf hale getirip verileri ziplist serialized halde tutmanın tüm configlerini bizlere bırakmış.

    Aslında configurasyon mantığı oldukça basit. Configler iki ana kriter üzerinden yapılabiliyor. Birincisi obje boyutu ikincisi de objenin eleman sayısı. Config dosyasına girip eğer benim objemin size’ı ya da eleman sayısı benim vereceğim sınır değerden küçük ise bunu serialized ziplist olarak tut, eğer verdiğim değerden büyük ise serialized ziplist olarak tutma normal data olarak tut. Çünkü veri boyutu büyüdükçe bunun ziplist olarak serialized edilmesi ve her read işleminde tekrar deserilized edilmesi zorlaşır dolayısıyla CPU kullanımı artar ve bu olayı çok fazla veri write-read’ı olan bir yapı üzerinde düşündüğümüzde işler daha da zorlayıcı hale gelir.

2. Ziplist Configurasyonları ve Redis Üzerinde Kullanımı

    Ziplist’in mantığı aslında bu kadar. Sınır değerleri belirleyip projenizin read-write trafiğine göre memory-Cpu trade-off’unu göz önüne alıp karar vermeniz gerekiyor. Şimdi teorik kısmı burada bırakıp somut olarak ziplist işlemlerini nasıl yapabileceğimize bakıp ve somut olarak deneyimlemeye çalışalım.

    Redisi kurduğumuz dosyanın içerisinde, redisin tüm configurasyonlarını yönettiğimiz redis.conf adında text based bir konfigurasyon dosyası var. Zipliste dair bütün ayarlamaları bu dosya üzerinden yapacağımız değişiklikler ile yöneteceğiz. Redis.conf’u açtıktan sonra, en alta ADVANCED CONFIG adında bir başlık göreceksiniz. Bu başlığın altında ziplist ayarları mevcut ve genel olarak çoğu veri tipleri için iki ana ayar mevcut ; -max-ziplist-entries settings ve -max-ziplist-value settings.  Entries  ayarı bize bir list, hash ya da sette encode edilebilecek maksimum eleman sayısını belirtirken, value ise objemizin boyutunun ziplist eşik sınırını belirtir. 

    Yukarıdaki resimde gördüğümüz kısım bahsettiğimiz configlerin hash veri yapısı için olan kısmıdır. Mavi kare içine alınan configlerin bize söylediği, benim hash objem 64 kb’den küçükse ve 512 elemandan daha az elemanı var ise bunu ziplist olarak encode ederek sakla. Eğer bu sınırların üzerindeyse normal hash datası olarak tut.  Advanced config başlığı altında benzer configurasonları diğer veri tipleri için de görebilirsiniz.

 Burası configurasyon kısmıydı. Şimdi bir de redis tarafına bakalım. 

   Aşağıda Redis Desktop manager üzerinden 4 alana sahip bir hash objesi yarattım. Daha sonra debug object . . . komutunu kullanarak objenin özelliklerini sorguladıgımızda bize objenin ziplist olarak encode edilip tutulduğunu söyledi. Zaten yukarıdaki configlerimizi göz önüne aldığımızda bunu bekliyorduk.

 Şimdi configlerimizi yeniden düzenleyerek sınır değerlerimizi azaltalım ve redis serverı restart edip aynı hash objesini tekrar yaratalım ve gözlemleyelim.

 Görüldüğü üzere bu sefer sınır değerleri aştığımız için redis ilgili veriyi encode etmeden olduğu gibi tuttu ve encoding tipini hashtable olarak döndü.

 Burada bir diğer önemli nokta ise bir sebepten dolayı bizim verdiğimiz sınır değerlerini geçen objenin tekrardan sınır değerini geçmesine sebep olan fazlalık alanları silinse ve tekrar sınır koşulları sağlasa da encode hale dönüşmez.

   Eğer max ziplist configlerinizi 500-2000 item rangeinde ve boyutunu da 128 byteın altında tutarsanız makul bir performans alırsınız. Ben şahsen max ziplist configlerimi 1024 item ve size olarak da 64 byte sınırında tutuyorum. Bu limitler memory kullanımını düşük tutmanıza ve performansı da yukarıda tutmanıza yardımcı olacaktır. Farklı memory-CPU sorunlarına sahipseniz de her zaman list, set, hash ve zset sizelarını küçük tutmanın memory kullanımını düşüreceği ve çoğu problemi çözeceğini aklınızın bir köşesinde tutun.

   Memory performansı için başka bir trick  bilgi daha ekleyeyim. Ziplist sınır değerleri ve memory yükünün rediste in-memory olarak tutulan data boyutuyla ilişkili olduğunu söyledik. Ancak bu data çoğu zaman sadece valuelardan oluşmaz. Valueların key’leri de vardır ki bunlar da bellekte tutulan stringlerdir. Dolayısıyla keyleri ana anlamlarıyla ilişkilerini bozmadan olabildiğince kısaltmalar kullanarak tutmak da hem veri boyutunuzu düşürecek hem ziplist encodingten faydalanma imkanı sağlayacak hem de küçük veri setleriyle çalışırken çok da fark teşkil etmese de çok büyük veri setlerinde gözle görülür farklar yaratacaktır.

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir