1、redis主從同步配置:
(0)主機配置:
伺服器名稱 | ip位址 | 執行個體6379 | 執行個體6380 | 執行個體6381 |
controller-node1 | 172.16.1.90 | 主 | 從 | 從 |
(1)确定主從:
1)将redis 6379執行個體确定為redis主伺服器;
修改redis 6379的"/data/6379/redis.conf"參數如下:
requirepass root
#redis安全保護模式認證密碼設定為root;
2)将redis 6380執行個體和redis 6381執行個體确定為redis從伺服器;
修改redis 6380和redis 6381執行個體的redis.conf檔案,修改參數如下:
vim /data/6380/redis.conf | vim /data/6381/redis.conf
requirepass root
#redis安全保護模式認證密碼設定為root;
replicaof 172.16.1.90 6379
#設定主從同步主庫的ip和端口号;
masterauth root
#設定主從同步主庫的密碼;
(2)啟動redis:
for nu in 79 80 81;do /data/63$nu/redis.sh start;done
START REDIS [ 确定 ]
START REDIS [ 确定 ]
START REDIS [ 确定 ]
netstat -tunlp | grep -E "6379|6380|6381"
tcp 0 0 172.16.1.90:6379 0.0.0.0:* LISTEN 1894/redis-server 1
tcp 0 0 172.16.1.90:6380 0.0.0.0:* LISTEN 1906/redis-server 1
tcp 0 0 172.16.1.90:6381 0.0.0.0:* LISTEN 1918/redis-server 1
(3)驗證:
1)主6379執行個體:
172.16.1.90:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.90,port=6381,state=online,offset=364,lag=0
slave1:ip=172.16.1.90,port=6380,state=online,offset=364,lag=1
172.16.1.90:6379> set lc1 1
OK
172.16.1.90:6379> keys *
1) "lc1"
2)從6380執行個體:
172.16.1.90:6380> info replication
# Replication
role:slave
master_host:172.16.1.90
master_port:6379
master_link_status:up
172.16.1.90:6380> keys *
1) "lc1"
3)從6381執行個體:
172.16.1.90:6381> info replication
# Replication
role:slave
master_host:172.16.1.90
master_port:6379
master_link_status:up
172.16.1.90:6381> keys *
1) "lc1"
2、redis主從同步手動切換主從:
(1)關閉主redis 6379執行個體:
172.16.1.90:6379> shutdown
not connected>
172.16.1.90:6380> info replication
# Replication
role:slave
master_host:172.16.1.90
master_port:6379
master_link_status:down
172.16.1.90:6381> info replication
# Replication
role:slave
master_host:172.16.1.90
master_port:6379
master_link_status:down
(2)将redis 6380執行個體提升為主:
172.16.1.90:6380> slaveof no one
OK
replicaof 172.16.1.90 6379";
(3)修改redis 6381執行個體指向新的主:
172.16.1.90:6381> slaveof 172.16.1.90 6380
OK
replicaof 172.16.1.90 6380";
(4)驗證:
1)redis 6380執行個體:
172.16.1.90:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.90,port=6381,state=online,offset=1102,lag=0
2)redis 6381執行個體:
172.16.1.90:6381> info replication
# Replication
role:slave
master_host:172.16.1.90
master_port:6380
master_link_status:up
(5)修複redis 6379執行個體:
replicaof 172.16.1.90 6380、masterauth root"
重新開機redis 6379執行個體,該執行個體就加入到了主從複制的叢集中了;
3、redis主從同步自動切換主從:
将環境恢複到未手動切換主從前一步;
masterauth root",并重新開機redis 6379執行個體;
(1)redis sentinel介紹:
redis sentinel是redis官方推薦的高可用解決方案,當用redis做master-slave的高可用方案時,加入master當機了,reids本
身(包括它的很多用戶端)都沒有實作主備切換,而redis-sentinel本身也是一個獨立運作的程序,它能監控多個master-slave集
群,發現master當機後能進行自動切換,實際上這意味着你可以使用Sentinel模式建立一個可以不用人為幹預而應對各種故障
的Redis部署。
(2)功能:
1)監控:
Sentinel不斷的檢查master和slave是否正常的運作;
2)通知:
如果發現某個redis節點運作出現問題,可以通過API通知系統管理者和其他的應用程式;
3)自動故障轉移:
能夠進行自動切換。當一個master節點不可用時,能夠選舉出master的多個slave中的一個來作為新
的master,其它的slave節點會将它所追随的master的位址改為被提升為master的slave的新位址,sentinel會
修改相應redis執行個體的redis.conf檔案添加或删除"replicaof <master-IP> <master-port>"配置;
4)配置提供者:
哨兵作為Redis用戶端發現的權威來源,用戶端連接配接到哨兵請求目前可靠的master的位址,如果發生故
障,哨兵将報告新位址;
5)sentinel的分布式特性:
很顯然,隻使用單個sentinel程序來監控redis叢集是不可靠的,當sentinel程序宕掉後(sentinel本身也
有單點問題,single-point-of-failure)整個叢集系統将無法按照預期的方式運作。是以有必要使用sentinel
叢集,這樣有幾個好處:即使有一些sentinel程序宕掉了,依然可以進行redis叢集的主備切換;如果隻有
一個sentinel程序,如果這個程序運作出錯,或者是網絡堵塞,那麼将無法實作redis叢集的主備切換
如果有多個sentinel,redis的用戶端可以随意地連接配接任意一個sentinel來獲得關于redis叢集中的資訊。
6)sentinel的自動發現機制:
A、sentinel叢集中各個sentinel都互相連接配接彼此來檢查對方的可用性以及互相發送消息;
B、不需要在sentinel中配置某個master的所有slave的位址,sentinel會通過詢問master來得到這些slave的位址的;
C、每個sentinel發送的消息中也包含了其目前維護的最新的master配置,如果某個sentinel發現自己的配置版本低于接收到的配
置版本,則會用新的配置更新自己的master配置;
D、當檢測到了新的sentinel,則将其加入到自身維護的master監控清單中;
7)通常使用sentinel叢集(每個redis執行個體設定一個sentinel)監控reids叢集;
(3)配置:
1)複制編譯包中的sentinel.conf檔案到各個redis執行個體的目錄:
sed -ri.bak "/#|^$/d" /application/redis/sentinel.conf
for nu in 79 80 81;do cp -a /application/redis/sentinel.conf /data/63$nu/;done
2)修改各個參數:
A、執行個體6379:
vim /data/6379/sentinel.conf
bind 172.16.1.90
port 26379
daemonize yes
pidfile "/data/6379/redis-sentinel.pid"
logfile "/data/6379/redis-sentinel.log"
dir "/tmp"
sentinel monitor mymaster 172.16.1.90 6379 2
sentinel auth-pass mymaster root
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
B、執行個體6380:
vim /data/6380/sentinel.conf
bind 172.16.1.90
port 26380
daemonize yes
pidfile "/data/6380/redis-sentinel.pid"
logfile "/data/6380/redis-sentinel.log"
dir "/tmp"
sentinel monitor mymaster 172.16.1.90 6379 2
sentinel auth-pass mymaster root
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
C、執行個體6381:
vim /data/6381/sentinel.conf
bind 172.16.1.90
port 26381
daemonize yes
pidfile "/data/6381/redis-sentinel.pid"
logfile "/data/6381/redis-sentinel.log"
dir "/tmp"
sentinel monitor mymaster 172.16.1.90 6379 2
sentinel auth-pass mymaster root
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
D、參數說明:
cat /data/6379/sentinel.conf
bind 172.16.1.90
#綁定的ip;
port 26379
#sentinel監聽的端口号;
daemonize yes
#sentinel以守護程序的方式運作;
pidfile /data/6379/redis-sentinel.pid
#sentinel以守護程序運作生成的pid檔案路徑;
logfile /data/6379/redis-sentinel.log
#sentinel日志檔案;
dir /tmp
#程序工作的目錄;
sentinel monitor mymaster 172.16.1.90 6379 2
#######################################################
#指定監控的master,2表示要2個sentinel認為redis
#主執行個體當機才有效;
#######################################################
sentinel auth-pass mymaster root
#連接配接redis驗證密碼,該密碼和redis.cof中配置的安全驗證密碼一緻;
sentinel down-after-milliseconds mymaster 30000
#超過30000毫秒(30s)後認為redis主執行個體當機;
sentinel parallel-syncs mymaster 1
########################################################
#發生主備切換時有1個slave同時對新的master進行同步,通常
#将這個值設為1來保證每次隻有一個slave 處于不能處理指令請
#求的狀态;
#########################################################
sentinel failover-timeout mymaster 180000
#當主從切換超過180000毫秒(180s)後認為主從切換失敗;
sentinel deny-scripts-reconfig yes
#########################################################
#不允許使用SENTINEL SET設定notification-script和
#client-reconfig-script;
#########################################################
(4)配置sentinel腳本檔案:
vim /data/6379/sentinel.sh
#!/bin/sh
. /etc/init.d/functions
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
172.16.1.90"
6379"
26379"
SENTINEL_HOME="/application/redis/src/redis-sentinel"
CONFIG="/data/$PORT/sentinel.conf"
SENTINEL_ADMIN="redis-cli -h $IP -p ${SENTINEL_PORT}"
SENTINEL_PID="/data/$PORT/redis-sentinel.pid"
[ $UID -eq 0 ] || {
echo "please use root"
exit 1
}
function usage (){
echo "USAGE:sh $0 |start|stop|restart|"
}
RETVAL=0
function check() {
RETVAL="$?"
if [ $RETVAL -eq 0 ]; then
action "$1" /bin/true
else
action "$1" /bin/false
fi
}
function start() {
if [ -f ${SENTINEL_PID} ]; then
echo "SENTINEL_${SENTINEL_PORT} IS RUNNIG......"
else
${SENTINEL_HOME} $CONFIG
check "START SENTINEL_${SENTINEL_PORT}"
fi
}
function stop() {
if [ -f ${SENTINEL_PID} ]; then
${SENTINEL_ADMIN} shutdown &>/dev/null
check "STOP SENTINEL_${SENTINEL_PORT}"
else
echo "SENTINEL_${SENTINEL_PORT} IS STOP......"
fi
}
function main(){
if [ $# -eq 1 ]; then
case "$1" in
start)
start
sleep 2
;;
stop)
stop
sleep 2
;;
restart)
stop
start
;;
*)
usage
;;
esac
else
usage
fi
}
main $*
chmod u+x sentinel.sh
說明:仿照上面的腳本,完成redis 6380執行個體、redis 6381執行個體的sentinel腳本;
(5)啟動各個sentinel執行個體:
for nu in 79 80 81;do /data/63$nu/sentinel.sh start;done
netstat -tunlp | egrep "26379|26380|26381"
tcp 0 0 172.16.1.90:26379 0.0.0.0:* LISTEN 2475/redis-sentinel
tcp 0 0 172.16.1.90:26380 0.0.0.0:* LISTEN 2477/redis-sentinel
tcp 0 0 172.16.1.90:26381 0.0.0.0:* LISTEN 2485/redis-sentinel
(6)驗證:
1)關閉主redis 6379執行個體:
172.16.1.90:6379> shutdown
not connected>
2)通過sentinel日志檢視主從接替過程:
tailf /data/6380/redis-sentinel.log
2673:X 17 May 2019 23:21:03.206 * +slave slave 172.16.1.90:6380 172.16.1.90 6380 @ mymaster 172.16.1.90 6379
2673:X 17 May 2019 23:21:33.363 * +slave slave 172.16.1.90:6381 172.16.1.90 6381 @ mymaster 172.16.1.90 6379
2673:X 17 May 2019 23:26:45.840 # +sdown master mymaster 172.16.1.90 6379
2673:X 17 May 2019 23:26:45.907 # +new-epoch 1
2673:X 17 May 2019 23:26:45.909 # +vote-for-leader 73b994f2ff6ab006c450f8c5662861ab90ee1c04 1
2673:X 17 May 2019 23:26:45.911 # +odown master mymaster 172.16.1.90 6379 #quorum 2/2
2673:X 17 May 2019 23:26:45.911 # Next failover delay: I will not start a failover before Fri May 17 23:32:46 2019
2673:X 17 May 2019 23:26:46.384 # +config-update-from sentinel 73b994f2ff6ab006c450f8c5662861ab90ee1c04 172.16.1.90 26381 @ mymaster 172.16.1.90 6379
2673:X 17 May 2019 23:26:46.384 # +switch-master mymaster 172.16.1.90 6379 172.16.1.90 6381
2673:X 17 May 2019 23:26:46.385 * +slave slave 172.16.1.90:6380 172.16.1.90 6380 @ mymaster 172.16.1.90 6381
2673:X 17 May 2019 23:26:46.385 * +slave slave 172.16.1.90:6379 172.16.1.90 6379 @ mymaster 172.16.1.90 6381
2673:X 17 May 2019 23:27:16.424 # +sdown slave 172.16.1.90:6379 172.16.1.90 6379 @ mymaster 172.16.1.90 6381
3)檢視主從資訊:
A、redis 6380執行個體:
172.16.1.90:6380> info replication
# Replication
role:slave
master_host:172.16.1.90
master_port:6381
master_link_status:up
B、redis 6381執行個體:
172.16.1.90:6381> info replication
#Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.90,port=6380,state=online,offset=974710,lag=1
(7)将redis 6379執行個體啟動:
啟動redis 6379執行個體後,sentinel 3個運作程序中的一個會在"/data/6379/redis.conf"配置檔案最後一行
追加"replicaof 172.16.1.90 6381" 配置,然後重新開機redis 6379執行個體,這樣redis 6379執行個體就會被加入到集
群中作從伺服器;
(8)sentinel指令:
1)SENTINEL get-master-addr-by-name <master name>:
傳回給定名字的主伺服器的 IP 位址和端口号。
例:
[root@controller-node1 ~]# redis-cli -h 172.16.1.90 -p 26380
172.16.1.90:26380> sentinel get-master-addr-by-name mymaster
1) "172.16.1.90"
2) "6381"
2)PING :
傳回 PONG;
3)SENTINEL masters:
列出所有被監視的主伺服器,以及這些主伺服器的目前狀态;
4)SENTINEL master <master name>:
顯示指定master的資訊和狀态;
5)SENTINEL slaves <master name>:
列出給定主伺服器的所有從伺服器,以及這些從伺服器的目前狀态;
6)SENTINEL reset <pattern>:
重置所有名字和給定模式 pattern 相比對的主伺服器。 pattern 參數是一個 Glob 風格的模式。 重置
操作清楚主伺服器目前的所有狀态, 包括正在執行中的故障轉移, 并移除目前已經發現和關聯的, 主
伺服器的所有從伺服器和 Sentinel;
7)SENTINEL failover <master name>:
當主伺服器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移(不過發起故障轉
移的 Sentinel 會向其他 Sentinel 發送一個新的配置,其他 Sentinel 會根據這個配置進行相應的更新);
3、将redis和sentinel腳本加入開機自啟動:
chmod +x /etc/rc.d/rc.local
vim /etc/rc.d/rc.local
/data/6379/redis.sh start &>/dev/null
/data/6380/redis.sh start &>/dev/null
/data/6381/redis.sh start &>/dev/null
/data/6379/sentinel.sh start &>/dev/null
/data/6380/sentinel.sh start &>/dev/null
/data/6381/sentinel.sh start &>/dev/null
加入開機自啟動在啟動的時候可能由于主節點不能及時啟動,可能導緻主節點轉換,但這都不是問題,
sentinel能做好任何故障的轉移,除了sentinel選舉票數(當機較多)不夠;
4、sentinel模式下主從同步叢集擴容:
以redis 6381執行個體為主庫為例;
(1)建立新的redis 6382執行個體:
mkdir -p /data/6382/
cp -a /data/6379/sentinel.conf /data/6382/
cp -a /data/6379/sentinel.sh /data/6382/
cp -a /data/6379/redis.conf /data/6382/
cp -a /data/6379/redis.sh /data/6382/
(2)修改sentinel.sh、redis.conf、redis.sh檔案的參數為對應執行個體的端口号和路徑并確定sedis.conf配置檔案中
有以下參數:
requirepass root
#redis安全保護模式認證密碼設定為root;
replicaof 172.16.1.90 6381
#設定主從同步主庫的ip和端口号;
masterauth root
#設定主從同步主庫的密碼;
(3)修改sentinel.conf的配置檔案指向新的主:
bind 172.16.1.90
port 26382
daemonize yes
pidfile "/data/6382/redis-sentinel.pid"
logfile "/data/6382/redis-sentinel.log"
dir "/tmp"
sentinel monitor mymaster 172.16.1.90 6381 2
sentinel auth-pass mymaster root
sentinel parallel-syncs mymaster 1
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
(4)将新的redis 6382執行個體加入到開機自啟動即可;
5、小結:
(1)叢集有密碼驗證的情況下每個redis執行個體必須要有的參數:
requirepass root
#redis安全保護模式認證密碼設定為root;
masterauth root
#設定主從同步主庫的密碼;
哪個redis執行個體為主,哪個redis執行個體為從,由sentinel選舉,然後在各個執行個體redis.conf檔案中增删
replicaof <master ip> <master prot>參數來決定;
(2)從節點的隻讀是預設的(是對從節點的一種保護,有助于主從的一緻性),但是需要在redis 執行個體的
redis.conf檔案中設定replicaof <master ip> <master prot>參數從節點隻讀才能生效;
(3)redis主從同步是實時異步增量同步;