Redis ile Uygulama Gelistirmek

Redis, günden güne popülerliği artan bir NoSQL veritabanı. Bense bu yazımda, bir geliştirici gözüyle redis ne olduğuna, kısaca uygulamalarınızın hangi bölümlerinde kullanmanızın yararlı olacağına ve vagrant ile redis’i nasıl geliştirme ortamında kullanabileceğinize değineceğim.

Redis Nedir?

En basit haliyle Redis, key-value şeklinde tasarlanmış bir NoSQL veritabanıdır. Tam olarak anlamak için yandaki NoSQL üçgenine bakabiliriz. NoSQL veritabanlarını sıkça birbirine karıştıran biri olarak bu üçgen bana kısaca konuyu özetliyor. Resmi aldığım yazının orjinaline buradan erişebilirsiniz.

Günümüzde kullanılan çoğu programlama dillerinde benzer key-value yapılarını bellekte bilgi saklamak için kullanıyoruz. Örneğin Java da Map yapılarında, ya da C#’ta Dictionary yapılarında key-value şeklinde yapılara rastlamak mümkün. Zaten Redis in açılımına baktığımızda da “Remote Dictionary Service” olduğunu görüyoruz.

Peki Redis’i farklı kılan ne? Öncelikle redis çok hızlı. Sitesinde paylaşılan banchmark’lara göre saniyede 100 bin operasyonu yürütebiliyor. Bunu nasıl yapıyor derseniz, sizin çalıştırdığınız tüm operasyonları bellekte çalıştırıyor ve size bellekteki veriyi dönüyor. Tüm veriyi bellekte tuttuğundan bu derece seri çalışabiliyor. Arzu edilirse, diske yazma seçenekleri de sunuyor. Ben diske yazma ile ilgili kısımlarına çok girmeyeceğim, fakat arzu eden olursa buradan konunun derinine inebilir.

Herşeyi bellekte tuttuğunu söyledik. Bu durumda insanın aklına hemen çok fazla bellek kullanabileceği geliyor. Fakat, redis tek bir iş yapmaya ve bu işi iyi yapmaya odaklanmış. Redis, hiç bir veri barındırmazken bellekte sadece 1 mb yer kaplıyor. Eğer siz basit bir key-value eşlemesi, örneğin <String,String> şeklinde bir eşleme, tutmak isterseniz, bir millyon adedi bellekte sadece 100 mb yer kaplıyor. Yok ben bu kadar basit veriler tutmayacağım benim verilerim daha karmaşık derseniz, <Hash, Obj> şeklindeki verilerin (burada value alanındaki nesnemizin 5 kırılımı olduğunu varsayıyoruz) bir milyon adedi ise bellekte sadece 200mb yer kaplıyor.

Redis vs Memcached vs MongoDB

İnternette, redis ile ilgili araştırma yaparken en çok bu üçünün karşılaştırıldığını gördüm. Okuduğum farklı kaynaklardan çıkardığım sonuçlar aşağıdaki gibi. Çok detayına girmek istemiyorum. Memcached yine sadece bellekte çalışan başka bir key-valie yapısı. MongoDB ise döküman şeklinde veri saklamanıza olanak sağlayan başka bir NoSQL veritabanı.

RedisMemcachedMongoDB
Bellekten Çalışmaxx
Diske Yazma(Persistent)xx
String’ten farklı veri tipleri desteğixx
Mutithreadedxx
Bellekten daha büyük verilerin desteklenmesix
Hızının dayandığı üst limitBellekBellekDisk

Redis Kullanım Örnekleri

Son geliştirdiğimiz projeye başlarken, farklı redis kullanım örneklerine baktım. Biz clustered bir yapıda verilerin dağıtılması ve hızlı erişilmesi adına redis kullanıyoruz. Ne demek istediğimi biraz daha açayım isterseniz.

Hemen hemen her dilde key-value şeklinde veri saklayabileceğiniz, veri yapılarının olduğundan bahsetmiştim. Bu sebepten bellekte veriyi cache’leyen bir yapı yazmak kolay bir iş. Singleton ve thread safe bir sınıf yaratıp (Double-Check-locking yapıp, gerekli önlemleri alıp vs.) bunun içerisinde bir Map tutup benzer bir yapı sağlayabilirsiniz. Belirli bir yere kadar da işinizi görebilir. Ya da doğruca Ehcache’te kullanabilirsiniz. Her durumda clustered bir ortama geçtiğinizde sorun yaşadığınızı göreceksiniz. Tamam siz bellekte veriyi tuttunuz da bu verinin doğruluğunu, güncelliğini nasıl sağlayacaksınız? Bu veriyi cluster’ınızda dağıtmanız ve cluster çerçevesinde singleton ve threadsafe yapmanız gerekir. (Tabi bunu Hazelcast kullanarak rahatlıkla yapabilirsiniz, sadece node (jvm) başına 2500$ gibi bir ücret ödemeniz gerekir.) Bu durumda verinizi en hızlı ve güvenli şekilde Redis kullanarak dağıtabilirsiniz. Emin olun Jgroups ya da benzeri bir yapı ile verinizi kendinizi dağıtsanız bile, redis daha performanslı çalışacaktır. Mantıksal olarak kodunuzu ne kadar hafifleteceğine girmiyorum bile. Üstüne üstlük, çok az bellek harcadığından, toplam tükettiğiniz bellekte azalacaktır. Hatta Tomcat kullanıyorsanız, tomcat session’larını farklı tomcat sunucu üzerine, redis kullanarak bile dağıtabilirsiniz.

Bir diğer kullanım örneği olarak, şöyle bir durum düşünün. Uygulamanızda öyle veriler olabilir ki, RDB’nizde bu verileri tutmanız saçmadır.  Fakat kullanıcınız tekrar geldiğinde de bu verileri görmesinde fayda vardır. Fakat kullanıcınızın ne kadar zaman da bir geleceğini bilmiyorsunuz. Yani bu verilerinizi önceki örnekteki gibi session’da tutmanız pek mümkün değil. Kullanıcının cookie’sinde de tutmak istemiyorsunuz, çünkü bu verileri analiz edip reklamlarınızı bu veriler ışığında yapmak isteyebilirsiniz. Bunun en güzel örneklerinden biri kullanıcınınız alış veriş sepeti. Kulanıcınız sepete bişeyler atmış fakat alım yapmamış olabilir. Bir sonraki gelişinde sepeti boş göstermek istemezsiniz. Fakat sepette neler eklediğini de bilmek istersiniz ki reklamlarınızı buna göre yönlendirin. Redis bu duruma da çok uygun. Hem liste şeklinde veri tipleri olduğundan çok rahatlıkla saklayabiliyorsunuz, hem uzun süreli saklama yapabiliyorsunuz, hemde bunları çok kısa sürede yapıyorsunuz.

İlk örneği ben bir sonraki yazımda, spring-data ve spring-cache ile nasıl gerçekleyeceğinizi anlatacağım. Eğer daha fazla kullanım örnekleri ile ilgileniyorsanız, Twitter vaka analizini özellikle tavsiye ederim. Redis, Stackoverflow, twitter, pinetrest gibi ortamlarda kendini kanıtlamış bir araç olduğundan diğer kullanımlarının analizleri de internette mevcut. Bir kaç tanesini aşağıda veriyorum.

Diğer örnekler:

Redis Kurulumu

Development mankinesine kurulum yapacağım için kurulumun nasıl yapılacağını Vagrant kullanarak anlatacağım. Vagrant, yazılım ekibinizin aynı ortamda geliştirme yapmasına olanak sağlayan bir araç. Alt tarafta isteğinize bağlı olarak VirtualBox ya da vmware kullanarak sanallaştırma yapıyor. Eğer sisteminizde vagrant kurulu değilse kurulum yapmanızın tam zamanı.

Vagrant kurulumunu yaptıktan sonra geliştirme ortamınızda yeni bir klasör yaratın. Örneğin ben ubuntu-redis isminde bir klasör yarattım. Daha sonra bu klasörün içerisine girin ve aşağıdaki komutu çalıştırın.

Bu komut klasörünüzü vagrant için hazırlayacak. Bu işlem sonunda klasörünüzde Vagrantfile isminde bir dosya yaratıldığını göreceksiniz. Şimdi bu dosyayı açıp aşağıdaki şekilde dosyayı değiştirin.

Vagrantfile

Kısaca bu dosyanın neler yaptığından bahsedeyim.

  • config.vm.box: Hangi sistem image’ini kullanarak sanal makinenizi ayağa kaldıracağınızı belirtiyor. Ben ubuntu/trusty64’i seçtim yani Ubuntu 14.04 LTS sürümünü kullanıyorum. Eğer başka bir image seçmek istiyorsanız bu adresten bakıp istediğinizi seçebilirsiniz.
  • config.vm.network: Bu satırda oluşturacağımız sanal makine ile ne şekilde bağlantılı olacağımızı belirliyoruz. “private_network” diyerek kendi makinemiz(Host) ile sanal makine(Guest) arasında yeni bir ağ kurulmasını istediğimizi belirtiyoruz. Bu ağda sadece iki makine bulunacak. Bu yeni makinenin ip’sini de 192.168.33.10 olarak ayarlıyoruz. Bu arada normalde yerel ağda 10.x.x.x şekilnde ip’ler kullanılıyor. Burada vereceğiniz ip yerel ağınızla ilişkili değil.
  • config.vm.provision: Bu şekilde başlayan satırlarda da makine kurulduktan sonra ne yapmak istediğimizi belirtiyoruz. Örnekteki Vagrantfile’da, sadece bir shell çalıştıracağımızı belirtmişiz. Shell script’inde öncelikle redis derlemek için gerekli olan paketleri yükleyecek. Daha sonra redisin sitesinden son redis versiyonunu indirip derleyecek. En son adımda da redisi sistem başlangıcında çalışan bir uygulama olarak kaydedecek.

Şimdi tüm hazırlığımızı yaptığımıza göre vagrant ile sanal makinemizi ayağa kaldırabiliriz. Bunun için aşağıdaki komutu çalıştırıyoruz.

Vagrant öncelikle kullandığımız image’ı (ubuntu/trusty64) indirecek. Bunu tek seferlik yapacak. Yani eğer başka bir uygulama için yine bu image’a ihtiyaç duyarsa, bir daha indirmeyecek. Sonra makineyi bizim verdiğimiz ayarlarda çalıştırıp ilgili işlemleri yapacak. Burada config.vm.provision ile verdiğimiz işlemleri sadece makinemizi ilk çalıştırdığımızda yapacak. Daha sonra makinemizi kapatıp açtığımızda bu işlemleri bir daha yapmayacak.

Son

Kurulumun doğru çalıştığına emin olmak için iki farklı yöntem kullanabiliriz. Ya vagrant ssh ile doğruca mekineye bağlanırız ve redis-cli üzerinden işlemlerimizi gerçekleştiririz ya da redis desktop manager üzerinden uygulamamızı test edebiliriz. Her iki durumda da redis’e bağlantı sağlarken, 192.168.33.10 ip adresini, 6379 portunu kullanacağız. Eğer ek bir ayar yapmadıysanız redis bağlantı sırasında kullanıcı adı ve şifre bilgisi sormayacaktır.

Unutmadan belirteyim, ayağa kaldırdığınız sanal makineyi kapatmak için aşağıdaki komutu kullanabilirsiniz.

Bir sonraki yazımda, Spring-Data kütüphanesini kullanarak Redis ile nasıl haberleşileceğini ve Spring-Cache kullanarak nasıl işlemleri otomatik olarak redis’e cache’leyebileceğinizi anlatacağım.

Gist

  • Mesut Özen

    Elinize sağlık çok güzel olmuş.