Redis的冗餘方案(keepalived, HAProxy, Redis Sentinel)
如果你在尋找Redis的冗餘方案,我找到了下面的方案,我想可以來嘗試一下這個方案。
「Highly Available Redis Cluster | Simplicity is the keynote of all true elegance」
最初曾考慮使用Pacemaker 來構建,因為Redis作者推出Sentinel的方案,因此本文使用Sentinel方案。
軟體列表及版本:
OS: CentOS 6.6
Redis: 2.8.19
HAProxy: 1.5.11
Keepalived: 1.2.13
Sentinel控制Redis的 Master / Slave之間的自動容錯移轉。
Sentinel對Master / Slave的監控管理的效果非常好,但因為Master的轉移無法使得用戶端始終串連同一個IP地址。下面需要使用HAProxy提供VIP的方案來實現。
HAProxy把所有的Redis伺服器(在我們的例子中Master和Slave兩台)作為LB的成員,並確保Master的健全狀態檢查。
Slave伺服器在這裡是作為Master的Standby,並不能做分布式的訪問。
Client可以提供Sentinel查詢Master的IP地址,Master IP地址的變化不能由Sentinel直接通知到Client。
在Slave晉陞為Master之後,如果舊的Master突然啟動,這時舊Master可以直接通過HAProxy分配到訪問。如果希望Sentinel立即把舊Master轉為Slave,而不是臨時的,取消Server的自動啟動是一個好主意。
在HAProxy的方案中,Client使用keepalived中VRRP協議提供一個虛擬IP來訪問Redis。
讓我們一一來設定。 Redis Sentinel
redis-sentinel.conf
port 2379logfile /var/log/redis/sentinel.logdir /tmpsentinel monitor mymaster 192.168.1.20 6379 2sentinel auth-pass mymaster my-redis-passwordsentinel down-after-milliseconds mymaster 30000sentinel parallel-syncs mymaster 1sentinel failover-timeout mymaster 180000# sentinel notification-script mymaster /var/redis/notify.sh# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
Master的名字mymaster,你可以用任何字串指定。此外,您還可以設定多個Master名字,如mymaster1和mymaster2。這樣你可以用一組Sentinel管理多個Redis的叢集。
只需要指定Master,Sentinel會依次從Master中獲得Slave的資訊。 HAProxy
haproxy.conf
global log 127.0.0.1 local2 notice maxconn 4096 chroot /var/lib/haproxy user nobody group nobody daemondefaults log global mode tcp retries 3 option redispatch maxconn 2000 timeout connect 2s timeout client 120s timeout server 120sfrontend redis bind :6379 default_backend redis_backendbackend redis_backend option tcp-check tcp-check send AUTH\ my-redis-password\r\n tcp-check expect string +OK 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 redis1 192.168.1.21:6379 check inter 1s server redis2 192.168.1.22:6379 check inter 1s
tcp-check發送一個字串,期望一個匹配的字串應答。上面的配置是在一個TCP會話中順序執行,反斜線需要在空格的前面。AUTH命令發送密碼,一旦正確會應答一個OK,發送包含PING的字串,會應答PONG, 發送INFO REPLICATION會應答包含OK字串的Master,你可以看到一個活著的Master。如果不需要認證及PING,也可以不發送它們。 keepalived
由於多播(multicast)的packet 資料流問題,這裡設定單播(unicast)。
keepalived.conf
global_defs { notification_email { admin@example.com } notification_email_from keepalived@example.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id 主機名稱}vrrp_script check_haproxy { script "pkill -0 -x haproxy" # haproxy的過程中存在確認 interval 1 # 每隔1秒運行 fall 2 # 連續判斷2次失敗 raise 2 # 成功判斷2次為正常}vrrp_instance REDIS { state BACKUP # nopreempt 2台作為BACKUP interface eth0 smtp_alert virtualrouter_id 51 # 在同一子網內的唯一號碼 priority 101 # 數字較大的為Master advert_int 1 # VRRP報文的發送間隔 nopreermpt # 不要自動故障恢複 unicast_peer { # 配置unicast而不是multicast 192.168.1.32 # 指定夥伴的IP地址 } authentication { auth_type PASS auth_pass hogehoge # 最多8個字元的字串 } virtual_ipaddress { 192.168.1.30 # VIP } track_script { check_haproxy } # 在晉陞Master時執行的指令碼 (當然這裡不需要設定任何東西) # notify_master /some/where/notify_master.sh
是不是有點誇張
雖然可以提供 Ansible playbook來構造配置,是不是感覺有點誇張。我想這僅僅是個Active / Standby配置而已。
有效利用Sentinel,通過增加Redis複製數來分布負載。由一對HAProxy來管理多個Redis叢集(Sentinel可以是一組),儘管這是個不錯的配置,但對於簡單的Active / Standby來說過於複雜。
另外,對於高速的Redis,相比HAProxy的長的等待時間來說確實會產生額外的負擔。
通過redis-benchmark簡單地測試結果,效能只有原來的一半。(原來很快,希望達到相近效能)
可以考慮去掉HAProxy,但keepalived非常有必要,通過keepalived返回的VIP總是可用Redis的Master,由Redis Sentinel 管理Redis的Failover。
當Redis的Master切換後,由keepalived 切換Redis的主機為新的Master。
這個方案是我參考下面的這篇文章「Redis推薦的使用Keepalived的HA方案 」。
fujiwara寫到keepalived 現在仍不支援 VRRP unicast,但我可以在雲端服務中使用,如EC2,因為單播可以使用。
在keepalived的notify_master中,調用 redis-cli的slaveof NO ONE命令,把一個Redis晉陞為Master,並把變更寫到redis.conf中以反映這種變化。
CONFIG REWRITE是在2.8版本中增加的命令,在fujiwara 寫這篇文章時還不支援。
當切換到BACKUP時,你也可以使用notify_backup,把Redis切換到slave。
keepalived.conf
global_defs { notification_email { admin@example.com } notification_email_from keepalived@example.com smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id 主機名稱}vrrp_script check_redis { script "/some/where/check_redis.sh" # 檢查redis interval 2 # 每隔2秒運行 fall 2 # 連續判斷2次失敗 raise 2 # 成功判斷2次為正常 }vrrp_instance REDIS { state BACKUP # nopreempt 2台作為BACKUP interface eth0 smtp_alert virtualrouter_id 51 # 在同一子網內的唯一號碼 priority 101 # 數字較大的為Master advert_int 1 # VRRP報文的發送間隔 nopreermpt # 不要自動故障恢複 unicast_peer { # 配置unicast而不是multicast 192.168.1.32 # 指定夥伴的IP地址 } authentication { auth_type PASS auth_pass hogehoge # 最多8個字元的字串 } virtual_ipaddress { 192.168.1.30 # VIP } track_script { check_redis } # Master 在晉陞Master時執行的指令碼 notify_master /some/where/notify_master.sh # notify_backup /some/where/notify_backup.sh }
這很簡單,如果主/備方式,你可以參考這些配置。
原文:
http://blog.1q77.com/2015/02/redis-ha/