24 Temmuz 2015 Cuma

Redis Sentinel'e geçin rahat edin :)

Uzun zamandır yazmayı planladığım ama hep ertelediğim bir konuyu sizlerle paylaşmak istiyorum.

Vitringez de memory cache olarak master-slave yapısında Redis kullanıyoruz. Bir süre önce (2014 Haziran) ciddi sorunlar yaşamaya başladık. Sorun Redis tarafında oluyordu. Araştırmalarım neticesinde bizim sorunumuzu Redis Sentinel'in çözeceğini gördüm. Önce local de bazı testler yaptık. Sonrasında ise alt yapıda ufak güncellemeler yaptık. credis kütüphanesini kullanarak yeni yapıyı yayına aldık. O gün bugündür çok memnunuz. Sağladığı otomatik ayağa kaldırma mekanizması ile çok rahat ettik.

Şimdi birlikte bir çalışma yapalım.
1. İlk olarak redis kurulumu yapın.
brew install redis


2. Şuradaki https://github.com/volkan/redis-work dosyaları bir klasöre indirin.
git clone git@github.com:volkan/redis-work.git
3. Sentinel leri aktif hâle getiriyoruz. Failover mekanizması için en az iki sentinel aktif olmalı. Ben bunları logları rahat takip etmek için ayrı tablarda açtım.
redis-sentinel redis-sentinel_26379.conf
redis-sentinel redis-sentinel_26380.conf
4. Redisleri aktif hâle getiriyoruz. (Ayrı tablarda açma olayı redisler içinde geçerli.)
redis-server redis_6381.conf
redis-server redis_6380.conf
redis-server redis_6379.conf
5. Sentinel durumunu kontrol ediyoruz;
redis$  redis-cli -h localhost -p 26379 info     
Aşağıda görüldüğü üzere henüz işlem yapılmıyor.
➜  redis git:(master) redis-cli -h localhost -p 26379 info     
# Server
redis_version:2.8.17
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:447fbed5d78be577
redis_mode:sentinel
os:Darwin 14.4.0 x86_64
arch_bits:64
multiplexing_api:kqueue
gcc_version:4.2.1
process_id:22338
run_id:db7af31f3bcacd0cd7433cb3aadc03751059f9fe
tcp_port:26379
uptime_in_seconds:351
uptime_in_days:0
hz:18
lru_clock:11625915
config_file:/Users/volkan/project/redis/redis-sentinel_26379.conf

# Sentinel
sentinel_masters:0
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
6. Sentinel'e master redis'i verip takip etmesini istiyoruz. Bu işlemi iki sentinel içinde yapıyoruz.
redis-cli -h localhost -p 26379 SENTINEL monitor mymaster 127.0.0.1 6381 2
redis-cli -h localhost -p 26380 SENTINEL monitor mymaster 127.0.0.1 6381 2
Sonrasında aldığımız çıktı da son satır önemli.
master0:name=mymaster,status=ok,address=127.0.0.1:6381,slaves=2,sentinels=2
➜  redis git:(master) redis-cli -h localhost -p 26379 info     
# Server
redis_version:2.8.17
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:447fbed5d78be577
redis_mode:sentinel
os:Darwin 14.4.0 x86_64
arch_bits:64
multiplexing_api:kqueue
gcc_version:4.2.1
process_id:22338
run_id:db7af31f3bcacd0cd7433cb3aadc03751059f9fe
tcp_port:26379
uptime_in_seconds:511
uptime_in_days:0
hz:13
lru_clock:11626075
config_file:/Users/volkan/project/redis/redis-sentinel_26379.conf

# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6381,slaves=2,sentinels=2
Sentinel de eklemeler sonrası slaveleri bulup gerekli çalışmaları yapıyor;
[22338] 24 Jul 01:09:42.412 # +monitor master mymaster 127.0.0.1 6381 quorum 2
[22338] 24 Jul 01:09:42.459 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
[22338] 24 Jul 01:09:42.459 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
[22338] 24 Jul 01:10:31.881 * +sentinel sentinel 127.0.0.1:26380 127.0.0.1 26380 @ mymaster 127.0.0.1 6381
7. 6381 olan master'ı kapatıyoruz! Burada bizim verdiğimiz gecikme süresine göre sentinel devreye girip bir slave'i master yapıyor.
[22338] 24 Jul 01:12:55.430 # +sdown master mymaster 127.0.0.1 6381
[22338] 24 Jul 01:12:55.489 # +new-epoch 1
[22338] 24 Jul 01:12:55.489 # +vote-for-leader 5f89e827f873bb2bf7acb7f898c21f0903bd80cb 1
[22338] 24 Jul 01:12:55.522 # +odown master mymaster 127.0.0.1 6381 #quorum 2/2
[22338] 24 Jul 01:12:55.522 # Next failover delay: I will not start a failover before Fri Jul 24 01:18:55 2015
[22338] 24 Jul 01:12:56.637 # +config-update-from sentinel 127.0.0.1:26380 127.0.0.1 26380 @ mymaster 127.0.0.1 6381
[22338] 24 Jul 01:12:56.637 # +switch-master mymaster 127.0.0.1 6381 127.0.0.1 6380
[22338] 24 Jul 01:12:56.637 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
[22338] 24 Jul 01:12:56.639 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
Tekrar info komutu çalıştırdığımızda durum aşağıdaki gibi. 6381 olan port 6380 olarak değişmiş. ➜ redis git:(master) ✗ redis-cli -h localhost -p 26379 info
master0:name=mymaster,status=ok,address=127.0.0.1:6380,slaves=2,sentinels=2
8. Kalan son master 6380 redisini kapattım. Kontrol ettiğimde kendisinin master yapıldığını gördüm.
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=2
Eğer yeni bir makine havuza ekleyecekseniz mutlaka çalışan master'a slave olarak eklemelisiniz. Sentinel bir kere bir makineyi takip etmeye başlarsa sonrasında onu doğru konuma yerleştirir. Birden fazla makine üzerinde çalışırken bir şekilde birbirlerini görmeyebilirler. Bundan emin olmak için aşağıdaki komutu bir sentinel üzerinde çalıştırıp kontrol edebilirsiniz. "protected mode no" olmalı. Ayrıca en az 3 sentinel kullanmalısınız. (Daha fazla olacaksa bu sayı tek sayı olmalı 3,5,7 gibi.)
SENTINEL ckquorum mymaster


Sonuç olarak bu harika nimeti kullanması gördüğünüz üzere oldukça kolay. credis kütüphanesi üzerinden sorgularınızı slave  makinelere dağıtık bir şekilde gönderip verimliliği artırabilirsiniz.

İyi kod yazmalar :)

3 yorum:

Haydar dedi ki...

Redis konusunda yaşanan sorun neydi? Ne olunca sorun oluyor bilmek adına iyi olabilir.

Volkan dedi ki...

Merhaba Haydar,

Haklısın güzel soru. Eksikleri sorularla tamamlamak iyi oluyor. Teşekkür ederim.

Master redis yoğunluk nedeniyle çalışamaz hâle gelip ölü olarak çalışıyordu. Process var ama işlem yapmıyordu. (Basit kontroller redisin gidişini algılamıyordu)

Sentinel bu gibi durumları görüp hemen makineyi değiştirdi. Böyle olunca aslında sorunun o makineye özgü bir durum olduğunu anladık. Başka zamanlarda da redis'in kapandığı oldu. Biz bunlardan önce HAProxy ile bu sorunu çözmeye çalışmıştık ama verim alamadık. Sentinel sonrası Redis konusunda çok rahatladık.

Ayrıca sentilen üzerinden slave lere sorgu göndermekte işimizi kolaylaştırdı. Ben sentinel'e isteği gönderiyorum hangi slave'e göndereceğini kendi seçiyor. Kod tarafında bir rastgelelik kullanmak gerekmiyor.

Haydar dedi ki...

Teşekkürler. Güzel bir yazı olmuş.Elinize sağlık.