Neden Redis Kullanırız ?
Redis bir open-source key-value database serverdır. Bunlara ek olarak data structure server olarak da bilinmektedir.
Redis diğer NoSQL veritabanlarına göre içinde data tipleri bulunduran bir yapıya sahiptir. Örneğin, rediste key’e karşılık gelen valuelerin string olma gibi bir zorunluluğu yoktur. Redis Lists, hash ve sets gibi veri tiplerini destekler.
Öncelikle Redis, uygulama performansını artırmaya yardımcı olmak için MySQL veya PostgreSQL gibi databaselerin önünde cache olarak kullanılan bir in-memory veritabanıdır. Redis hakkındaki bir diğer önemli konu ise verileri memory’de tutuyor olmasıdır. Redis dataları öncelikli olarak kendi koştuğu makinanın RAM’inde tutar. Performansının yüksek olmasının sebebi dataları memoryde tutmasıdır. Bunun dışında redis ile istenilirse RAM’de tutulan veriler disk’e de yazılabilir.
Kullanım alanları
- Nadiren değişen ve sık sık talep edilen veriler için kullanımı uygundur. Caching
- Sayaçlar
- Oturum (Session Verileri)
- Kuyruk işlemleri
- publish-subscribe mechanisms
Transaction YönetimiTransaction: Bir transaction içerdiği SQL ifadelerinin ya tamamını gerçekleştirir, ya da hiçbirini
gerçekleştiremez. İşlemlerin tamamı gerçekleşmediği sürece işlemlerin hiçbiri gerçekleşmemiş sayılır.
Bir müşteri kendi hesabından başka bir hesaba 1500 TL para transferi gerçekleştiriyor.
- Önce kişinin hesabından transfer edilecek olan 1500 TL tutar düşülmelidir.
- Sonra diğer kişinin hesabına transfer edilecek olan 1500 TL tutar eklenmelidir.
Bu işlemlerden birincisi gerçekleştikten sonra herhangi bir sorundan dolayı İkinci işlem
gerçekleşmezse hesaplarla ilgili ciddi sorunlar yaşanabilir.
Bu tür sorunları önlemek için transaction yapıları kullanılır.
Transaction her iki işlemi de tek bir işlem olarak ele alacağı için herhangi birisi gerçekleşmediği
zaman diğer gerçekleşen işlemleri de yok sayacaktır.
Yani gerçekleşen işlemi geri alacaktır(rollback).
Eğer işlemlerin tamamı sorunsuz bir şekilde gerçekleşirse, tüm İşlemleri kalıcı(commit) hale
getirecektir.
Çoğu database gibi redis de transaction yönetimini destekler. Transaction kullanarak, birden fazla redis commandini gruplayabilir, böylece bu commandlerin araya herhangi bir başka komut girmeden bir kerede hepsinin çalışacağını veya çalışmayacağını garanti edebilirsiniz.
Ancak redis transcationu ile ilgili bilinmesi gereken en önemli noktalardan biri rollback olmamasıdır. Bunun anlamı transcation içerisindeki komutlardan biri fail olursa kalanlar çalışmaya devam eder.
Örneğin, syntaxi doğru ama çalıştırılırken hata alınacak bir komut bu tip bir hataya sebebiyet verebilir. Burada bilinmesi gereken önemli husus, komutlardan biri hatalı olsa dahi diğer komutlar çalışmaya devam eder.
Redis Handling Failure
Redis, ilişkisel databaselerin aksine ACID prensibiyle çalışmayan bir NoSql çözümü olduğu için ve verileri memoryde tuttuğu için, olası bir felaket senaryosunda veri kaybetmemek için kendimizi her türlü felaket senaryosuna hazırlamamız gerekir
1.Persistency Ayarlarını Doğrulamak
Herhangi bir sıkıntı sebebiyle veri kaybıyla karşılaşma ihtimalimize karşı güvenlik önlemlerimizden biri persistence ayarlarımız olabilir. Redis persistence’ı iki farklı opsiyon ile destekler. Snapshotting ve Append-only file
- Snapshotting bizim belirlediğimiz belli zaman aralıklarıyla redisteki verinin snapshotını alır ve diske kaydeder. RDB snapshottingi db backupları gibi düşünebilirsiniz. Snapshotting özelliğiyle veri kaybetme olasılığınız her zaman vardır. RDB snapshotın mantığı belli aralıkla rediste belli sayıda key’in değişip değişmediğini kontrol ederek bu da göre snapshot almak üzerine kuruludur. Örneğin, bu aralığın 5 dakikada bir olduğunu varsayarkan ilk snapshottan sonraki 5 dakikalık aralığın 4. dakikasında server down olursa o 4 dakikaya kadar olan verileriniz henüz backup alınamadığı için kaybolur.
- Append-only file ise redise gelen her commandı kaydeder yani real time’a yakın bir veri koruyuculuğu sağlar. Bu sayede herhangi sebepten bir veri kaybı yaşadığımızda bu opsiyonlar ile verilerimizi geri yükleyebiliriz.
2.Çöken Bir Master Makineyi Değiştirmek
Bazı zamanlar makinaların bir sebepten down olma durumu söz konusu olabilir. Bu sebep kötü makine, kötü memory belki de elektriklerin gitmesi bile olabilir. Ancak sebepleri bir yana, en nihayetinde redis serveri değiştirmemiz gerekecektir. Eğer bir grup redis serverını replicasyon ve persistence ile koşturuyor isek bu durumla mücadele edebilecek şansımız var demektir.
Bir örnek senaryo üzerinden ilerleyelim.
Master olarak hareket eden A makinamız, bir de slave olarak davranan B makinamız olsun. A bir sebepten dolayı ağdan kopmuş olsun ve bir de C makinamız olsun. Bu durumda plan gayet basit. B makinasına SAVE keywordü üzerinden güncel snapshot üretmesini söyleyeceğiz. Bu snapshotu C makinasına kopyalayacağız. Ve daha sonra redisi C makinasında ayağa kaldıracağız. Ve en sonunda B makinasına Cnin slaveyi olmasını söyleyeceğiz. Ya da bir alternatif yol olarak da slaveyi yeni mastera çevirmek isteyebilirz.
Her iki durumda da, Redis kaldığı yerden devam edebilecektir. Bundan sonraki tek işimiz, istemci yapılandırmamızı uygun sunuculara okumak ve yazmak için güncellemek ve isteğe bağlı olarak Redis’i yeniden başlatmamız gerekirse disk üstü sunucu yapılandırmasını güncellemektir
Redis Scaling
Scaling tek bir makinenin gücünün sınırlarını gördüğümüzde veri ve performans ihtiyacımız artmaya devam ediyorsak karşımıza çıkan en net çözümdür. Scaling out yani yatayda ölçekleme, processleri birden fazla makinaya dağıtıp süreçleri paralelde işletmek üzerine kuruludur. Dolayısıyla bu da dağıtık bir sistem inşa etmek etmek demektir. Rediste scalingi read ve write kapasitesini artırmak için ayrı çözümler olarak kulanabiliriz. Read kapasitesini artırabilmek için read-only slave serverlar ekleyerek yani replicasyon özelliğinden faydalanarak, Write kapasitesinin sınırlarını artırmak için de sharding yönetimi kullanabiliriz.
Redis Read Scale Etmek
1- Redis Replication
Replikasyon dediğimiz yöntem aslında ana master serverimizde tuttuğumuz verimizin diğer serverlarda kopyasının tutulmasıdır. Redis de ölçeklenmeye yardımcı olmak açısından replikasyonu desteklemektedir. Redis her ne kadar çok hızlı olsa da zaman zaman darboğaza düştüğü durumlar olabilir ve bu gibi durumlarda da replikasyon özelliği yardımımıza koşabilir.
2- Master-Slave Replikasyonu
Redis master-Slave replikasyonunu destekler. Yani bir master serveriniz ana redis serverınızdır ve diğer slaveler bu mastera subscribe olup masterda veri güncellendikçe kendilerini update eder ve orjinal veriye sahip olur.
Slave serverlar iki ana amaç için kullanılabilir. İlki redis master serverınızın yavaş çalıştığı durumlarda yükü bölmek ve sistemi hızlandırmak. Redis master, serverınızda çok fazla operasyon olduğunda read operasyonlarını slavelere dağıtıp yükü hafifleterek serverı hızlandırabilirsiniz. Tabi slavelere güncel veriyi dağıtacak olan node master node olduğundan writelar yine master node üzerinden ilerlemeye devam eder.
İkinci bir kullanım amacı ise handling failure. Eğer master nodeunuz herhangi bir sebepten çökerse, slave nodedaki veriyi kullanarak yeni bir master node’a taşıyabilir ya da direkt slave node’u master olarak kullanabilirsiniz.
Bazen bir mastera çok sayıda slave bağlandığında da performans kayıpları olabilir. Aslında redis serverlarının temelde master veya slave olması arasında fark yok. Dolayısıyla bu durumda biz master node’a slaveleri bağlarken slavelere de diğer slaveleri bağlayabiliriz. Yani master’ın slaveyi, slave’in de başka bir slave’i olabilir. Bu durumda bütün veriyi slavelere master üzerinden değil, bir kısmına master üzerinden diğer kısmına diğer slaveler üzerinden dağıtabiliriz. Ayrıca redis append-only özelliği ile replikasyonu bir arada kullanırsak veri kaybını sıfıra indirgeyebiliriz.
3- Redis Read Scale
Redis serverlarımızı scale etmeden önce, performans attırmak için gözden geçirebileceğimiz tüm seçenekleri gözden geçirmeliyiz eğer ki elimizdeki seçenekler tükendiyse sclale etme sürecine girmemiz yerinde olacaktır.
- Eğerki küçük yapılar kullanıyorsak, ziplist sizeımızın çok büyük olmadığından emin olmamız gerekir.
- Kullandığıımız veri yapılarının performans etkilerini gözden geçirmemiz gerekir.
- Eğer ki redise cachelemek için büyük objeler gönderiyorsak bu objeleri compress etmek ve netword bandwidth’ini read ve writelar için azalmayı düşünmeliyiz.
- Redis pipelining ve connection poolingi özelliklerini de kullanmayı unutmamalıyız.
Eğer performansa dair herşeyi yaptığımızı düşünüyorsak geriye bir tek scale etmek kalıyor . Read performansını arttırmanın en temel ve basit yolu redise read-only slave serverlar eklemektir. Bu read-only slave serverlar master servera bağlı olup masterın replicalarını alıp real-time'a yakın bir sürede güncel olurlar. Yani siz master server’a bir data yazarsınız ve master da bunu slaveleriyle paylaşır. Burada önemli nokta master çökerse ne olacağıdır.
Bir slave mastera bağlandığında masterın snapshotu yani bağlandığı anda masterdaki verinin kopyası alınır ve slave’e gönderilir. Eğer birden fazla slave mastera bu sırada bağlanırsa tüm slavere ayrı snapshot çekilmesi yerine hepsine aynı snapshot gider ve bu performans açısından oldukça fayda sağlar. Ancak çok fazla slave mastera bağlandığı takdirde, master slave arasında trafik artışı ve performans problemi çıkabilir. Bunu azaltmanın yolu da master’a slave bağlarken slave’e de başka slaveler bağlamaktır. Yani master-slave-slave şekilde bir ağaç yapısı kurmaktır.
Redisin replicasyon ve failover durumları için kullanılabilmek için yeni bir toolu olan redis sentinel de göz önünde bulundurulabilir. Aslında Redis sentinel bir redis server modudur ve bu nodeda redis normal bir redis server olarak hareket etmez. Bunun yerine master ve slavelerin davranışını ve statusunu takip eden bir yapı olarak hareket eder. Masterin fail olması durumunda redis sentinel var olan slaveler arasından bir master seçebilir. Bu slave master seçildikten sonra sentinel tüm diğer slaveleri yeni master üzerinden bağlayacaktır.
Redis Write ve Memory Kapasitesini Scale Emtek
Replication yöneti ile redisin read’ini ölçekleyebileceğimizden bahsettik. Write’ların ise hala master node üzerinden yürümeye devam edeceğinden de bahsettik. Peki write yükü artığında ve write’ı güncellememiz gerektiğinde ne yapmalıyız? Burada artık sharding devreye girer. Normal şartlarda shardingle memory kapasitemizi artırmayı düşünürüz ancak bu yöntem eğer ki makinemizin gücü son noktaya ulaştuysa write performansımızı artırmak için, geçerli bir yöntemdir. Yani redis üzerinde tek makina sınırlarına ulaştıysa artık bu memoryi ve dolayısıyla write’ı scale edebilmek için sharding metodunu kullanabiliriz.
Redis’de veri parçalama (partitioning), tüm verileri birden çok Redis örneğine bölme tekniğidir, böylece her örnek yalnızca anahtarların bir alt kümesini içerecektir
Eğer ki memory’i optimize etmek ve performansı maximize etmek için her şeyi denediysek ve elimizdeki makinenin sınırlarını gördüysek, artık verimizi farklı instancelara sharding etmenin vakti gelmiş demektir.
Ne Zaman Sharding Kullanmalıyız ?
Çok büyük dataları yönetiyorsak ve tek bir makinenin memorysiyle yetinmek yerine çok fazla bilgisayarın gücüne ihtiyaç duyuyorsak, hesaplama gücünü birden çok CPU, birden çok bilgisayar arasında ölçeklendirip ve ağ bant genişliğini kullanmak istiyorsak shardinge başvurabiliriz. Tabi verileri yatayda parçalara ayırmak yani sharding yapmak ve bunları ayrı makinalara koymak yani dağıtık bir sistem oluşturmak kulağa kazandıran bir yöntem gibi gelse de bunun bazı trade-offları var ve sistemleriniz dağıtık hale geldiğinde sorunlarınız da dağıtık hale geliyor. Rediste shardinge başvurmadan önce shardingin getireceği bazı sıkıntılardan bahsedebiliriz.
- Sharding sonucu farkı instancelarda bulunan multiple keylerle operasyon yapamazsınız.Farklı
- redis instancelarında bulunan keyler ile transaction işlemi yapamazsınız.
- Key bazlı partitioning yapamazsınız. Mesela çok büyük bir list veya sorted list objesini farklı instance’a koymak gibi.
- Backup ve persistence yönetimi eskiye göre çok daha komplex olur. Çünkü çok daha fazla RDB ve AO fileları ile uğraşmanız gerekir backup involves aggregation (merging) of the RDB files from many instances.
- Runtimeda clusterınıza instance eklemek veya silmek data misbalancingleri oluşturur ki bunun çözümü de preshardingtir.

PRESHARDİNG YÖNTEMİ
Rediste sharding yapısını kullanmaya başladığınızda runtimeda instance eklemek ve silmek oldukça zordur. Ancak bunun üstesinden gelmek için kullanabileceğiniz teknikler de var. Bunlardan biri preshardingtir.
Preshardingin mantığı oldukça basittir. Bir makinada başlangıçta birden fazla redis instanceı oluşturursunuz ki bu 32 ya da 64e kadar çıkabilir çünkü redis oldukça lightweight bir üründür. Bu sayede data storageın büyümesi gerektiğinde ve redisin bunu handle etmesi gerektiğinde redis instancelarını bir makineden başka makineye taşımak mümkündür. Eğer ki bir adet redis serverınız varsa ve bir adet daha eklemeniz gerekiyorsa redis instancelarınızın yarısını diğer servera taşırsınız. Bu işlemi her redis instanceı bir servera karşılık gelene kadar yapabilirsiniz.
Redis Architecture
- Single Redis Instance
- Redis High Availability
- Redis Sentinel
- Redis Cluster
Single Redis Instance
Single Redis İnstance, Redis'in en basit dağıtımıdır. Kullanıcıların servislerini büyütmelerine ve hızlandırmalarına yardımcı olabilecek küçük örnekler oluşturup çalıştırmalarına olanak tanır. Ancak dezavantajlarıda vardır. Örneğin,Redis fail veya unavailable olursa yapılan tüm istemci çağrıları başarısız olur ve bu nedenle sistemin genel performansını ve hızı düşer. Redis, verileri kalıcı kılmak için ayarlanmamışsa, yeniden başlatma veya yük devretme durumunda veriler kaybolur.
Redis High Availability
Secondaryler mainin replicalarıdır. Birden fazla olabilirler. Redisten okuma durumunda read operasyonları için ölçeklenmeye fayda sağlarlar ve main instancesi fail yada unavailable olduğunda onun yerine main olarak atanabilirler.