Format data yang didukung antara lain strings, hashes, lists, sets, sorted sets. Perusahaan sekelas twitter pun menggunakan Redis untuk caching system. Yang dapat mengungurangi load ke database atau storage utama lainnya.
Tapi kita tidak akan tentang feature atau penggunaan redis. Kita akan membahas tentang redis clustering dan failover (satu host mati, yang lain akan membackup).
Bagaimana mencluster redis menjadi banyak instance dan mengatasi jika redis master mengalami kegagalan dengan waktu downtime sekecil mungkin (sebisa mungkin zero second downtime).
Istilahnya mungkin High Availability.
Requirement untuk tutorial ini :
- redis 3.0xx (include sentinel)
- HAProxy 1.5xx
Kebanyakan dari kita mungkin awalnya memakai redis dengan cara seperti ini.
Satu atau lebih application server konek ke single redis (satu redis master). sebenarnya tidak masalah karena akses redis sangatlah cepat.
Tapi setelah beberapa saat, setelah jumlah app server yang connect bertambah dan jumlah request dari client naik jug. Maka jumlah koneksi ke redis akan bertambah juga secara signifikan.
Jumlah key bertambah, memory consume naik. Kemungkinan pada suatu saat akan terjadi kegagalan di redis, misal out memory atau disk corrupt. App server juga ikut gagal karen tidak bisa membaca data dari redis.
Maka terjadilah downtime. Downtime disini bukan berarti app server mati, tetapi hanya client tidak bisa mengakses datanya karena kegagalan di redis.
Sehingga perlu dilakukan backup. Bisa menaikan memory di redis instance. Atau bisa jadi malah ganti VM untuk redis. Kemudian copy data yg lama. Proses ini tentu membutuhkan waktu beberapa menit bahkan beberapa jam sampai app server bisa mendapatkan datanya kembali.
Kemudian kita coba cara lain seperti dibawah ini.
Konfigurasi redis.conf
Start redis : ./redis-server PATH/redis.conf
#redis-01
port 6380
bind 192.168.33.10
#redis-02
bind 6381
bind 192.168.33.20
slaveof 192.168.33.10 6380
App server tetep connect ke satu redis master. Tetapi di belakang redis master ada satu atau bisa banyak redis slave.Ini bisa disebut satu redis custer.
Redis cluser bisa diartikan kumpulan redis yang tugasnya sama biasanya berisi : 1 Master + N x Slave)
Redis Slave tugasnya melakukan syncronization data ke redis master. Redis sifatnya read-only. Lalu apa keuntungannya?
Ketika Redis master mengalami kegagalan (dengan berbagai alasan). Maka kita cukup mempromote salah satu Redis slave
untuk menjadi redis master. App server diganti pointing ke redis master yg baru, dan redis slave uang lain disetting sebagai anggota (slave) dari Redis master yang baru.
Kita tinggal berkonsentrasi untuk perbaikan redis master yang bermasalah lagi. Ketika sudah up bisa di kembalikan ke cluster sebagi master atau slave.
Downtime yang terjadi bisa jauh lebih berkurang karena kita tinggal menganti konfigurasi host redis di app server dan setting master-slave satu-persatu di sisi redis cluster. Kemudian restart semua service.
Apa yang harus kita lakukan untuk mengurangi downtime lagi?
Sekarang kita coba memasang Redis Sentinel. Apa itu Sentinel? (dari redis.io)
"Redis Sentinel provides high availability for Redis. In practical terms this means that using Sentinel you can create a Redis deployment that resists without human intervention to certain kind of failures.Intinya sentinel itu bisa melakukan monitoring ke sebuah redis cluster. Bisa mendekteksi pada saat master mengalami kegagalan. Maka sentinel otomatis akan mempromote salah satu savle menjadi master, dan mereset semua konfigurasi slave untuk pointing ke master yang baru.
Redis Sentinel also provides other collateral tasks such as monitoring, notifications and acts as a configuration provider for clients.
This is the full list of Sentinel capabilities at a macroscopical level (i.e. the big picture):
Sentinel constantly checks if your master and slave instances are working as expected.
Sentinel can notify the system administrator, another computer programs, via an API, that something is wrong with one of the monitored Redis instances.
Automatic failover. If a master is not working as expected, Sentinel can start a failover process where a slave is promoted to master, the other additional slaves are reconfigured to use the new master, and the applications using the Redis server informed about the new address to use when connecting.
Sentinel acts as a source of authority for clients service discovery: clients connect to Sentinels in order to ask for the address of the current Redis master responsible for a given service. If a failover occurs, Sentinels will report the new address."
dan jika master yang lama sudah hidup kembali. Sentinel akan otomatis mensetting menjdai slave. Begitu seterusnya posesnya jika ada master yang gagal.
Downtime akan jauh lebih berkurang karena konfigurasi master-slave yang baru dihandle oleh Sentinel. Kita cukup mengganti konfigurasi di app server mau connect ke host redis yang mana.
Konfigurasi : sama dengan master-slave sebelumnya kita tambahkan satu mesin lagi yang berfungsi sebagai sentinel (sentinel.conf)
#sentinel conf
port 16380
bind 192.168.33.10
sentinel monitor redis-cluster 192.168.33.10 6380 1
sentinel down-after-milliseconds redis-cluster 5000
sentinel failover-timeout redis-cluster 10000
sentinel config-epoch redis-cluster 26
Start sentinel : ./redis-server PATH/sentinel.conf --sentinelSentinel akan otomatis mendeteksi redis mana aja yang menjadi anggota dari cluster redis-01 (192.168.33.10)
#sentinel log
1793:X 12 Aug 05:16:55.269 # Sentinel runid is b2e912eedf1416b61ecb8688180c64f00f0e12b6
1793:X 12 Aug 05:16:55.269 # +monitor master redis-cluster 192.168.33.10 6380 quorum 1
1793:X 12 Aug 05:16:56.269 * +slave slave 192.168.33.20:6381 192.168.33.20 6381 @ redis-cluster 192.168.33.10 6380
Kemudian kita stop redis master pertama (3310:6380), seolah-olah sedang down.
# sentinel failover
1793:X 12 Aug 05:17:37.074 # +sdown master redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.075 # +odown master redis-cluster 192.168.33.10 6380 #quorum 1/1
1793:X 12 Aug 05:17:37.076 # +new-epoch 27
1793:X 12 Aug 05:17:37.076 # +try-failover master redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.077 # +vote-for-leader b2e912eedf1416b61ecb8688180c64f00f0e12b6 27
1793:X 12 Aug 05:17:37.078 # +elected-leader master redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.078 # +failover-state-select-slave master redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.152 # +selected-slave slave 192.168.33.20:6381 192.168.33.20 6381 @ redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.152 * +failover-state-send-slaveof-noone slave 192.168.33.20:6381 192.168.33.20 6381 @ redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.244 * +failover-state-wait-promotion slave 192.168.33.20:6381 192.168.33.20 6381 @ redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.538 # +promoted-slave slave 192.168.33.20:6381 192.168.33.20 6381 @ redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.538 # +failover-state-reconf-slaves master redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.595 # +failover-end master redis-cluster 192.168.33.10 6380
1793:X 12 Aug 05:17:37.595 # +switch-master redis-cluster 192.168.33.10 6380 192.168.33.20 6381
1793:X 12 Aug 05:17:37.596 * +slave slave 192.168.33.10:6380 192.168.33.10 6380 @ redis-cluster 192.168.33.20 6381
1793:X 12 Aug 05:17:42.656 # +sdown slave 192.168.33.10:6380 192.168.33.10 6380 @ redis-cluster 192.168.33.20 6381
Otomatis redis kedua (33.20:6381) akan menjadi master.
andris-MacBook-Pro:~ andri$ redis-cli -h 192.168.33.20 -p 6381
192.168.33.20:6381> role
1) "master"
2) (integer) 0
Ketika redis pertama (33.10:6381) tadi up kembali, maka ia akan otomatis menjadi slave
#redis-01 is up and will be slave of redis-01
1793:X 12 Aug 05:20:10.131 # -sdown slave 192.168.33.10:6380 192.168.33.10 6380 @ redis-cluster 192.168.33.20 6381
1793:X 12 Aug 05:20:20.101 * +convert-to-slave slave 192.168.33.10:6380 192.168.33.10 6380 @ redis-cluster 192.168.33.20 6381
Cek redis role yang baru, yang sudah jadi slave. andris-MacBook-Pro:~ andri$ redis-cli -h 192.168.33.10 -p 6380
192.168.33.10:6380> role
1) "slave"
2) "192.168.33.20"
3) (integer) 6381
4) "connected"
Masalah dari konfigurasi diatas adalah app server tidak langsung tahu mana redis master yang baru, setelah redis master yang lama masih mati.
Kita bisa memakai HAProxy untuk mengatasi ini. HAproxy biasanya digunakan untuk load balance http request. Install haproxy bisa lewat apt-get jika memakai linux ubuntu. Pada versi 1.5x keatas sudah support untuk koneksi TCP (redis memakai TCP). HAProxy akan selalu melakukan healty-check ke semua redis yang sudah didaftarkan mencari mana yang master. Ketika Sentinel sudah merubah master-slave yang baru, HAProxy akan langsung tahu mana yang master. App server atau client connect TCP ke HAProxy host bukan ke redis langsung (tanpa tahu proses master-slave dibelakang). Proses downtime di app server akan jauh lebih turun lagi.
#HAProxy conf
defaults REDIS
log global
mode tcp
timeout connect 4s
timeout server 30s
timeout client 30s
frontend ft_redis
bind *:6378 name redis
default_backend backend_redis
backend backend_redis
option tcp-check
tcp-check connect
tcp-check send PING\r\n
tcp-check expect string +PONG
tcp-check send info\ replication\r\n
tcp-check expect string role:master
tcp-check send QUIT\r\n
tcp-check expect string +OK
server redis_01 192.168.33.10:6380 check inter 1s
server redis_02 192.168.33.20:6381 check inter 1s
Konfigurasi redis sentinel sama dengan sebelumnya.
Percobaan yang dilakukan ke HAProxy (33.80:6379)
andris-MacBook-Pro:~ andri$ redis-cli -h 192.168.33.80 -p 6378
192.168.33.80:6378> ping
PONG
192.168.33.80:6378> role
1) "master"
2) (integer) 169
3) 1) 1) "192.168.33.20"
2) "6381"
3) "169"
192.168.33.80:6378> set foo "bar"
OK
192.168.33.80:6378> get foo
"bar"
192.168.33.80:6378> get foo
"bar"
Kita matikan redis-master pertama (33.10:6380).
#sentinel log
2721:X 12 Aug 09:19:58.218 # +failover-state-reconf-slaves master redis-cluster 192.168.33.10 6380
2721:X 12 Aug 09:19:58.316 # +failover-end master redis-cluster 192.168.33.10 6380
2721:X 12 Aug 09:19:58.317 # +switch-master redis-cluster 192.168.33.10 6380 192.168.33.20 6381
2721:X 12 Aug 09:19:58.318 * +slave slave 192.168.33.10:6380 192.168.33.10 6380 @ redis-cluster 192.168.33.20 6381
2721:X 12 Aug 09:20:03.375 # +sdown slave 192.168.33.10:6380 192.168.33.10 6380 @ redis-cluster 192.168.33.20 6381
Data masih tetap ada, tanpa kita ganti konfigurasi redis di app server.
192.168.33.80:6378> get foo
"bar"
Sekian tutorial ini, semoga bisa bermanfaat. :)