搭建redis高可用系統

搭建一個redis高可用系統

1、單個實例

當系統中只有一臺redis運行時,一旦該redis掛了,會致使整個系統沒法運行。php

單個實例css

2、備份

因爲單臺redis出現單點故障,就會致使整個系統不可用,因此想到的辦法天然就是備份(通常工業界認爲比較安全的備份數應該是3份)。當一臺redis出現問題了,另外一臺redis能夠繼續提供服務。git

備份github

3、自動故障轉移

雖然上面redis作了備份,看上去很完美。但因爲redis目前只支持主從複製備份(不支持主主複製),當主redis掛了,從redis只能提供讀服務,沒法提供寫服務。因此,還得想辦法,當主redis掛了,讓從redis升級成爲主redis。redis

這就須要自動故障轉移,redis sentinel帶有這個功能,當一個主redis不能提供服務時,redis sentinel能夠將一個從redis升級爲主redis,並對其餘從redis進行配置,讓它們使用新的主redis進行復製備份。vim

自動故障轉移c#

4、動手實踐

1.環境安全

這裏使用三臺服務器,每臺服務器上開啓一個redis-server和redis-sentinel服務,redis-server端口爲8000,redis-sentinel的端口爲6800,修改默認端口是安全的第一步_bash

redis-server說明服務器

  • 192.168.56.101:8000  主

  • 192.168.56.102:8000  從

  • 192.168.56.103:8000  從

redis-sentinel說明

  • 192.168.56.101:6800

  • 192.168.56.102:6800

  • 192.168.56.103:6800

2.搭建redis系統

首先下載安裝redis

wget http://download.redis.io/releases/redis-3.2.8.tar.gz
tar zxvf redis-3.2.8.tar.gzcd redis-3.2.8
makecd src#複製redis相關命令到/usr/sbin目錄下,這樣就能夠直接執行這些命令,不用寫全路徑sudo cp redis-cli  redis-server  redis-sentinel   /usr/sbin/

在redis目錄下有redis.conf和sentinel.conf配置文件示例,使用sudo cp redis.conf sentinel.conf /etc/命令將兩個配置文件複製到/etc目錄下(固然也能夠在/etc/目錄新建配置文件),而後修改配置文件。

修改主redis-server配置文件內容以下:

port  8000           #修改端口是安全的第一步daemonize  yesbind  0.0.0.0
pidfile   /var/run/redis-8000.pid
logfile   /var/log/redis/redis-8000.log

修改從redis-server配置文件內容以下:

port  8000           #修改端口是安全的第一步daemonize  yesbind  0.0.0.0
pidfile   /var/run/redis-8000.pid
logfile   /var/log/redis/redis-8000.log
slaveof  192.168.56.101  8000    #從redis比主redis多這一行

啓動redis-server。

sudo redis-server /etc/redis.conf

三個redis服務啓動完畢後,進入命令行,執行info  replication查看當前主從配置。

主節點上查看主從信息

發現並無從節點信息。

3.主從間沒法通訊

這裏的緣由是防火牆屏蔽了8000端口,須要修改防火牆設置,開放8000端口(同理redis-sentinel的6800端口)。

# 打開防火牆配置文件,增長8000端口sudo vim /etc/sysconfig/iptables#修改完後,須要重啓防火牆sudo service iptables restart

增長8000端口和6800端口

而後從新進入主節點,查看主從信息,能夠發現兩個從節點信息,代表redis-server主從已經配置完畢。

主節點上查看主從信息

4.搭建redis-sentinel系統

redis-sentinel程序上面已經安裝過了,這裏只須要修改配置文件就能夠了。修改/etc/sentinel.conf,若是沒有建立便可。

修改sentinel.conf配置文件內容以下:

daemonize yes
port  6800logfile  /var/log/redis/sentinel.log
pidfile  /var/run/sentinel.pid
sentinel monitor master8000 192.168.56.101 8000 2#5秒內master6800沒有響應,就認爲SDOWNsentinel down-after-milliseconds master8000 5000  sentinel failover-timeout  master8000 15000

啓動redis-sentinel。

redis-sentinel  /etc/sentinel.conf

三個redis-sentinel服務啓動完畢後,鏈接任意sentinel服務能夠獲知當前主redis服務信息。

sentinel監控狀態

5、測試

1.把住redis停掉

redis-cli -h 192.168.56.101 -p 8000 shutdown

2.查看redis-sentinel的監控狀態

sentinel監控狀態

發現102這臺redis-server提高爲主庫。

至此,redis的高可用方案已經搭建完成。

6、客戶端程序

客戶端程序(如PHP程序)鏈接redis時須要ip和port,但redis-server進行故障轉移時,主redis是變化的,因此ip地址也是變化的。客戶端程序如何感知當前主redis的ip地址和端口呢?redis-sentinel提供了接口,請求任何一個sentinel,發送SENTINEL get-master-addr-by-name <master name>就能獲得當前主redis的ip和port。

獲取當前主redis的ip和port

客戶端每次鏈接redis前,先向sentinel發送請求,得到主redis的ip和port,而後用返回的ip和port鏈接redis。

這種方法的缺點是顯而易見的,每次操做redis至少須要發送兩次鏈接請求,第一次請求sentinel,第二次請求redis。

php請求sentinel程序代碼可參見:https://github.com/huyanping/redis-sentinel

更好的辦法是使用VIP,固然這對配置的環境有必定的要求,好比redis搭建在阿里雲服務器上,可能不支持VIP。

VIP方案是,redis系統對外始終是同一ip地址,當redis進行故障轉移時,須要作的是將VIP從以前的redis服務器漂移到如今新的主redis服務器上。

好比:當前redis系統中主redis的ip地址是192.168.56.101,那麼VIP(192.168.56.250)指向192.168.56.101,客戶端程序用VIP(192.168.56.250)地址鏈接redis,實際上鍊接的就是當前主redis,這樣就避免了向sentinel發送請求。

當主redis宕機,進行故障轉移時,192.168.56.102這臺服務器上的redis提高爲主,這時VIP(192.168.56.250)指向192.168.56.102,這樣客戶端程序不須要修改任何代碼,鏈接的是192.168.56.102這臺主redis。

VIP指向192.168.56.101

故障轉移後,VIP漂移指向192.168.56.102

7、漂移VIP

那麼如今的問題是,如何在進行redis故障轉移時,將VIP漂移到新的主redis服務器上。

這裏可使用redis sentinel的一個參數client-reconfig-script,這個參數配置執行腳本,sentinel在作failover的時候會執行這個腳本,而且傳遞6個參數<master-name>、 <role>、 <state>、 <from-ip>、 <from-port>、 <to-ip> 、<to-port>,其中<to-ip>是新主redis的IP地址,能夠在這個腳本里作VIP漂移操做。

sentinel client-reconfig-script master8000   /opt/notify_master6800.sh

修改三個服務器的redis-sentinel配置文件/etc/sentinel.conf,增長上面一行。而後在/opt/目錄下建立notify_master6800.sh腳本文件,這個腳本作VIP漂移操做,內容以下:

#notify_master6800.sh腳本內容#!/bin/bashMASTER_IP=$6  #第六個參數是新主redis的ip地址LOCAL_IP='192.168.56.101'  #其餘兩個服務器上爲192.168.56.102,192.168.56.103VIP='192.168.56.250'NETMASK='24'INTERFACE='eth1'if [ ${MASTER_IP} = ${LOCAL_IP} ];then   
    /sbin/ip  addr  add ${VIP}/${NETMASK}  dev ${INTERFACE}  #將VIP綁定到該服務器上
    /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
    exit 0else 
   /sbin/ip  addr del  ${VIP}/${NETMASK}  dev ${INTERFACE}   #將VIP從該服務器上刪除
   exit 0fiexit 1  #若是返回1,sentinel會一直執行這個腳本

如今當前主redis是192.168.56.102,須要手動綁定VIP到該服務器上。

/sbin/ip  addr add 192.168.56.250/24 dev eth1
/sbin/arping -q   -c 3 -A 192.168.56.250 -I eth1

而後,去另外一個服務器上經過VIP地址鏈接redis-server和redis-sentinel。

經過VIP鏈接redis


從上面也能夠看出當前主redis是192.168.56.102。

下面關閉這臺redis服務,看看VIP是否漂移到另外一臺服務器上。

redis-cli -h 192.168.56.102 -p 8000 shutdown


經過查詢sentinel發現192.168.56.103提高爲主。

經過訪問VIP鏈接redis,發現VIP確實指向了192.168.56.103。

8、總結

經過上面的操做,使用redis主從 + 哨兵(sentinel)+ 漂移VIP的方案搭建了一個redis高可用系統,但這個系統保證的是單個redis實例的高可用,因此適合業務比較小的應用。若是業務比較大,併發量比較高,建議搭建redis集羣,好比官方redis cluster,還有開源的codings集羣。

另外,漂移VIP可使用keepalived軟件來實現,這裏就很少介紹了。

相關文章
相關標籤/搜索