Redis Memory Optimizasyonu
Herkese selam, bu yazımda önce caching temel kavramları üzerinde kısa bilgiler verip sonrasında yazılım geliştirme mimarisinde sıkça başvurulan yöntemlerden biri olan Redis ile Distributed Caching yapısında “Redis’i nasıl daha verimli kullanabiliriz?” konusuna değineceğim.
Caching Nedir?
Geliştirdiğimiz uygulamalar üzerinde veriye daha hızlı ulaşmak, uygulamamızın kullanıcı deneyimini artırmak için başvurduğumuz yöntemlerden biri caching’tir. Veri kaynağına(veritabanı vb.) gidip disk üzerinde okuma yapma işlemimiz, RAM üzerinde okuma işlemine göre oldukça maliyetlidir. Bu yöntem ile ilgili verileri belirli parametrelere göre ön-belleğe alıp takip eden isteklerde veriye ulaşma maliyetimizi düşürmeye çalışırız.
Distributed Caching — Redis
Redis’in kurulumu ve kullandığınız mimariye göre implementasyonu ile bir çok makaleye rastlayabilirsiniz. Bu nedenle bu yazımda bu konuya değinmeyeceğim. Uygulamada Redis kurulumunu yaptığımızı varsayarak esas konu üzerine ilerliyorum.
Redis implementasyonunu yaptık. Verilerimizi string tipinde key-value olarak kaydedip okuyoruz. Peki Redis ile işimiz bitti mi? Hayır :)
Redis’te Memory Verimliliği
Eğer basit bir uygulamamız varsa, redis üzerinde oluşturduğumuz key sayısı azsa Redis üzerinde optimizasyon yapmamıza gerek kalmadan sorunsuz bir şekilde kullanabiliriz. Ancak milyonlarca key-value verilerinin olduğu, anlık binlerce eş zamanlı istek alan bir uygulamanız varsa ne yapmalıyız?
Tam bu aşamada Redis üzerinde yapacağımız düzenlemeler ile Redis’in verimli çalışmasını buna bağlı olarak uygulamamızın daha verimli çıktılar üretmesini sağlayabiliriz.
Daha mimari süreçlerinde karar verici olarak yer aldığım yoğun yük altında çalışan uygulamalarda Redis’in temel seviyede implementasyonunun yetersiz kaldığı noktada redis üzerinde memory optimizasyonu yapmamız gerekmişti. Redislab’ın önerileri ve bu uygulamalarda elde ettiğim deneyimlerden yola çıkarak önemli olduğunu düşündüğüm maddeleri aşağıda sıralıyorum;
1. Key — Daha kısa isimlendirmeler yapmak
Evet yanlış duymadınız Redis’e veri eklerken kullandığımız key isimlendirmelerini daha kısa tutun. İsimlendirme yaparken mümkün olduğunda açıklayıcı isimler vermeye çalışırız. Ancak milyonlarca key’e sahip bir Redis’iniz varsa bu isimlendirmeler gereksiz yere memory harcıyor olabilir. Küçük bir hesaplama ile buradaki kaybı/kazancı hesaplayalım;
Örnek key:
catalog.products.product.id.1234 → 32 karakter
Bunu aşağıdaki gibi daha kısa şekilde yazdığımızı düşünelim
cat.prod.id.1234 → 16 karakter
tek key üzerinde 16 karakterlik yani 16 byte’lık bir kazancımızın olduğunu görüyoruz. Her key üzerinden bu kadar kazanç elde edemeyeceğimiz için ortalama kazancımızı 10 karakter olarak hesaplarsak
1 000 000 000key x 10 byte = ~1GB memory kazanmış olduk !
2. Alternatif Serializer Kullanmak
Verileri Redis üzerine genellikle JSON formatında tutarız. Oysa Redis üzerinde serilize edilmiş verileri tutmak için özel bir veri değişken tipi bulunmaz. Redis bu verileri byte dizisi şeklinde tutar.
MessagePack
It’s like JSON.
but fast and small.
Aynı JSON gibi veri transferinde elde bulunan veriyi transfer edilecek formata çevirme veya gelen veriyi eldeki modele uydurabilmek için kullanılır. Bu işlemi performanslı ve verimli şekilde yapar. Bir binary serialization kütüphanesidir.
3. Duplicate Veriler
Redis üzerinde veri optimizasyonu için en temel sorulardan biri de veri tekrarı yapılıp yapılmadığının kontrol edilmesidir. Veri tekrarı bizim karşımıza 2 şekilde sorun olarak çıkar;
- Fazla Memory Kullanımı: aynı verinin defalarca farklı key’ler içinde kullanılması ile gereksiz memory kullanımı yapmış oluruz. Caching yapılarında uygulamamızı da bu mimariye hazırlamamız gerekir. Bu nedenle Redis’e veriyi olduğu gibi atmak her zaman çözüm olmayacaktır.
- Veri Güncelliği: İlgili veri güncellendiğinde bu verinin bulunduğu tüm key’leri güncelmememiz gerekir. Veriyi merkezileştirmediğimiz dünyada hangi key içinde güncellenecek verinin yer aldığını takip edemediğimiz bir düzleme gideriz
4. Verileri Birleştirmek (Hash Kullanımı)
Birleştirilebilir küçük string verilerin tespit edilip bir hash altında toplanması Redis üzerinde olumlu çıktıları görmemize katkı sağlayacaktır. Hash string veri tipine göre memory üzerinde verimlilik sağlamaktadır. Örnek senaryo;
Setting adında bir tablomuz olduğunu düşünelim. Bu tabloda settingleri Key-Value şeklinde tutalım. Bu verileri cache’lerken doğrudan Redis’e string tipinde key-value olarak attığımızda her setting satırı için bir cache key üretmiş oluruz.
- Settings.IconPath: “/base/icons/”
- Settings.BannerPath: “/base/banners/”
Biz bu setting verilerini birleştirerek tek bir hash veri tipi altında toplayabiliriz. Bu durumda cache yapımız şu şekilde olacaktır
Settings →
Settings.IconPath : “/base/icons/”
Settings.BannerPath: “/base/banners/”
Bu yazımda daha önce kullandığım en temel Redis memory optimizasyonu yöntemleri hakkında bilgi vermeye çalıştım. Uygulamanıza göre incelemeye devam edildiğinde çok daha farklı iyileştirme alanları çıkabilir.
Bu konuda daha fazla bilgi alışverişi yapmak veya yazımda eksik gördüğünüz yerleri bana iletmek isterseniz ahmet@ozokutan.com mail adresim üzerinden iletişime geçebilirsiniz.
Teşekkürler.