1. Redis Sentinel 架構(gòu)搭建
我們使用經(jīng)典的一主二從 + 3個(gè)sentinel節(jié)點(diǎn)來搭建Redis Sentinel 架構(gòu)。架構(gòu)圖如下:
搭建步驟如下:
(1) 復(fù)制配置文件
把$REDIS_HOME/redis.conf
復(fù)制為redis_6379.conf
,$REDIS_HOME/sentinel.conf
復(fù)制為sentinel_26379.conf
,這樣做的原因有兩個(gè):
- 保留一份原來的配置文件做備份
- 命名中包括端口號(hào)可以很方便的知道使用這個(gè)配置文件將會(huì)占用哪個(gè)端口
[hadoop@node01 redis-4.0.12]$ cp redis.conf redis_6379.conf
[hadoop@node01 redis-4.0.12]$ cp sentinel.conf sentinel_26379.conf
其他兩個(gè)節(jié)點(diǎn)也執(zhí)行以上操作吟温。
(2) master redis.conf 配置
修改 master 節(jié)點(diǎn)的 redis_6379.conf,以下列出的修改過的或者相關(guān)的需要了解的配置路星,沒有列出的保持默認(rèn)即可溯街。
#################### 基礎(chǔ)配置 #####################
# 服務(wù)是否后臺(tái)運(yùn)行
daemonize yes
# 端口號(hào)
port 6379
# 日志文件存放位置
logfile /home/hadoop/logs/redis/6379/redis_6379.log
# pid 文件存放位置
pidfile /home/hadoop/pid/redis/6379/redis_6379.pid
# 持久化文件(AOF/RDB)存放位置
dir /home/hadoop/data/redis/6379
#################### RDB 相關(guān) #####################
# RDB文件的名稱
dbfilename dump.rdb
# 生成RDB文件的策略
save 900 1
save 300 10
save 60 10000
# RDB文件是否壓縮
rdbcompression yes
# 在寫入文件和讀取文件時(shí)是否開啟rdb文件檢查诱桂,檢查是否有損壞
rdbchecksum yes
#################### AOF 相關(guān) #####################
# 開啟AOF持久化機(jī)制
appendonly yes
# AOF文件的名稱
appendfilename "appendonly.aof"
# 寫AOF文件的策略
appendfsync everysec
# AOF文件重寫策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 同時(shí)在執(zhí)行 bgrewriteaof 操作和主進(jìn)程寫aof文件的操作時(shí),兩者都會(huì)操作磁盤
# 而 bgrewriteaof 往往會(huì)涉及大量磁盤操作
# 這樣就會(huì)造成主進(jìn)程在寫aof文件的時(shí)候出現(xiàn)阻塞的情形
# 如果 no-appendfsync-on-rewrite 參數(shù)設(shè)置為no呈昔,是最安全的方式挥等,不會(huì)丟失數(shù)據(jù),但是要忍受阻塞的問題
# 如果設(shè)置為yes堤尾,這就相當(dāng)于將 appendfsync 設(shè)置為no
# 這說明并沒有執(zhí)行磁盤操作肝劲,只是寫入了緩沖區(qū),因此這樣并不會(huì)造成阻塞郭宝,因?yàn)闆]有競爭磁盤
# 但是如果這個(gè)時(shí)候 redis 掛掉辞槐,就會(huì)丟失數(shù)據(jù)
no-appendfsync-on-rewrite no
# aof rewrite過程中,是否采取增量文件同步策略
# rewrite過程中,每 32M 數(shù)據(jù)進(jìn)行一次文件同步
# 這樣可以減少aof大文件寫入對(duì)磁盤的操作次數(shù)
aof-rewrite-incremental-fsync yes
# 是否加載破損的AOF文件
aof-load-truncated yes
# #################### 混合持久化 #####################
# 是否開啟redis-4.x新增的混合持久化機(jī)制
aof-use-rdb-preamble no
# #################### Master #####################
# 必須綁定一個(gè)IP或者主機(jī)名粘室,否則只識(shí)別127.0.0.1
# bind 192.168.239.101
bind node01
# 設(shè)置master的認(rèn)證口令為redis
# requirepass redis
# backlog大小
repl-backlog-size 1mb
# 快照同步的超時(shí)時(shí)間
repl-timeout 60
# 開啟無盤復(fù)制
repl-diskless-sync yes
# 無盤復(fù)制的延遲默認(rèn)為5s榄檬,是為了等待更多的slave連接
repl-diskless-sync-delay 5
# 是否開啟主從節(jié)點(diǎn)復(fù)制數(shù)據(jù)的延遲機(jī)制
# 當(dāng)關(guān)閉時(shí),主節(jié)點(diǎn)產(chǎn)生的命令數(shù)據(jù)無論大小都會(huì)及時(shí)地發(fā)送給從節(jié)點(diǎn)衔统,這樣主從之間延遲會(huì)變小
# 但增加了網(wǎng)絡(luò)帶寬的消耗鹿榜。適用于主從之間的網(wǎng)絡(luò)環(huán)境良好的場景
# 當(dāng)開啟時(shí),主節(jié)點(diǎn)會(huì)合并較小的TCP數(shù)據(jù)包從而節(jié)省帶寬锦爵。
# 默認(rèn)發(fā)送時(shí)間間隔取決于Linux的內(nèi)核舱殿,一般默認(rèn)為40毫秒。
# 這種配置節(jié)省了帶寬但增大主從之間的延遲险掀。適用于主從網(wǎng)絡(luò)環(huán)境復(fù)雜或帶寬緊張的場景
repl-disable-tcp-nodelay no
# 觸發(fā)快照同步的條件
# 如果增量同步的緩存大于256MB沪袭,或者超過60s大于64MB,則觸發(fā)快照同步
client-output-buffer-limit slave 256mb 64mb 60
# 主從節(jié)點(diǎn)進(jìn)行心跳的時(shí)間間隔
repl-ping-slave-period 10
(3) slave redis.conf 配置
修改兩臺(tái) slave 節(jié)點(diǎn)的 redis_6379.conf樟氢,以下列出的修改過的或者相關(guān)的需要了解的配置冈绊,沒有列出的保持默認(rèn)即可:
#################### 基礎(chǔ)配置 #####################
daemonize yes
port 6379
logfile /home/hadoop/logs/redis/6379/redis_6379.log
pidfile /home/hadoop/pid/redis/6379/redis_6379.pid
dir /home/hadoop/data/redis/6379
#################### RDB 相關(guān) #####################
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
rdbcompression yes
rdbchecksum yes
#################### AOF 相關(guān) #####################
# 注意這里關(guān)閉slave節(jié)點(diǎn)的AOF機(jī)制
appendonly no
# #################### 混合持久化 #####################
# 是否開啟redis-4.x新增的混合持久化機(jī)制
aof-use-rdb-preamble no
# #################### Slave #####################
# slave
# 必須綁定本臺(tái)機(jī)器的IP或者主機(jī)名
bind node02
# 指定 master 節(jié)點(diǎn)的IP和port
slaveof node01 6379
# 開啟從節(jié)點(diǎn)只讀
slave-read-only yes
# 從節(jié)點(diǎn)在處于快照同步期間是否對(duì)外提供服務(wù)
slave-serve-stale-data yes
# 從節(jié)點(diǎn)的成為master的優(yōu)先級(jí),這個(gè)數(shù)字越高埠啃,優(yōu)先級(jí)越高
slave-priority 100
# 如果 master 檢測到 slave 的數(shù)量小于這個(gè)配置設(shè)置的值焚碌,將拒絕對(duì)外提供服務(wù),0 代表霸妹,無論 slave 有幾個(gè)都會(huì)對(duì)外提供服務(wù)
min-slaves-to-write 1
# 如果 master 發(fā)現(xiàn)大于等于 ${min-slaves-to-write} 個(gè) slave 與自己的心跳超過此處配置的時(shí)間(單位s)
# 就拒絕對(duì)外提供服務(wù)
min-slaves-max-lag 10
# 節(jié)點(diǎn)間認(rèn)證口令,需要與master的requirepass的值一致
# masterauth redis
另一個(gè) slave 的配置中知押,只需要修改 bind
的值為自己的主機(jī)名或者IP即可叹螟,其他都和上面的配置一樣。
(4) sentinel.conf 配置
修該3個(gè)節(jié)點(diǎn)的 sentinel_26379.conf台盯,內(nèi)容如下:
bind node01
port 26379
daemonize yes
dir /home/hadoop/data/redis/26379
# 文件需要提前創(chuàng)建好
logfile /home/hadoop/logs/redis/26379/sentinel_26379.log
# sentinel monitor [master-name] [master-ip] [master-port] [quorum]
# 這里的[master-name]可以自定義罢绽,但涉及到[master-name]的參數(shù)都要相同
sentinel monitor mymaster node01 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
# sentinel auth-pass mymaster redis
# sentinel notification-script mymaster /tmp/xxx.sh
# sentinel client-reconfig-script mymaster /tmp/xxx.sh
不同的節(jié)點(diǎn)只需要修該bind
配置,修該為自己的IP或者主機(jī)名即可静盅。
這些配置具體的解釋以及配置的優(yōu)化會(huì)在下面的內(nèi)容中詳細(xì)說明良价。
(5) 啟動(dòng) Redis Sentinel 架構(gòu)
- 首先啟動(dòng) redis 主從架構(gòu)
[hadoop@node01 ~]$ redis-server /home/hadoop/apps/redis-4.0.12/redis_6379.conf
# 其余兩個(gè)節(jié)點(diǎn)執(zhí)行相同的命令
- 確認(rèn)3個(gè)redis 服務(wù)是否啟動(dòng)
[hadoop@node01 ~]$ redis-cli -h node01 -p 6379 ping
PONG
[hadoop@node01 ~]$ redis-cli -h node02 -p 6379 ping
PONG
[hadoop@node01 ~]$ redis-cli -h node03 -p 6379 ping
PONG
- 確認(rèn)主從關(guān)系
[hadoop@node01 ~]$ redis-cli -h node01 -p 6379 info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=192.168.239.102,port=6379,state=online,offset=378,lag=0
slave1:ip=192.168.239.103,port=6379,state=online,offset=378,lag=0
......
[hadoop@node01 ~]$ redis-cli -h node02 -p 6379 info replication
# Replication
role:slave
master_host:node01
master_port:6379
...
slave_priority:100
slave_read_only:1
connected_slaves:0
......
- 啟動(dòng) 3個(gè) sentinel 服務(wù)
edis-sentinel /home/hadoop/apps/redis-4.0.12/sentinel_26379.conf
或者
redis-server /home/hadoop/apps/redis-4.0.12/sentinel_26379.conf --sentinel
- 確認(rèn) sentinel 服務(wù)是否正常啟動(dòng)
[hadoop@node01 bin]$ redis-cli -h node01 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.239.101:6379,slaves=2,sentinels=3
到這里寝殴,Redis Sentinel 架構(gòu)搭建就已經(jīng)成功搭建!
2. Redis Sentinel 配置詳解
(1) quorum
# sentinel monitor [master-name] [master-ip] [master-port] [quorum]
sentinel monitor mymaster node01 6379 2
我們的配置中明垢,quorum = 2蚣常,quorum 參數(shù)用于故障發(fā)現(xiàn)和判定,例如將 quorum 配置為2痊银,代表至少有2個(gè)Sentinel節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)不可達(dá)抵蚊,那么這個(gè)不可達(dá)的判定才是客觀的。quorum 設(shè)置的越小溯革,那么達(dá)到客觀下線的條件越寬松贞绳,反之越嚴(yán)格。一般建議將其設(shè)置為Sentinel節(jié)點(diǎn)的一半加1致稀。
同時(shí) quorum 還與 Sentinel 節(jié)點(diǎn)的領(lǐng)導(dǎo)者選舉有關(guān)冈闭,至少要有max(quorum,num(sentinels) / 2 + 1)
個(gè)Sentinel節(jié)點(diǎn)參與選舉抖单,才能選出領(lǐng)導(dǎo)者Sentinel萎攒,從而完成故障轉(zhuǎn)移。例如有5個(gè)Sentinel節(jié)點(diǎn)臭猜,quorum=4躺酒,那么至少要有4個(gè)在線Sentinel節(jié)點(diǎn)才可以進(jìn)行領(lǐng)導(dǎo)者選舉。
(2) down-after-milliseconds
sentinel down-after-milliseconds mymaster 30000
每個(gè)Sentinel節(jié)點(diǎn)都要通過定期發(fā)送ping命令來判斷Redis數(shù)據(jù)節(jié)點(diǎn)和其余Sentinel節(jié)點(diǎn)是否可達(dá)蔑歌,如果超過了down-after-milliseconds
配置的時(shí)間(單位ms)且沒有有效的回復(fù)羹应,則判定節(jié)點(diǎn)不可達(dá),這個(gè)配置是對(duì)節(jié)點(diǎn)失敗判定的重要依據(jù)次屠。
優(yōu)化說明:down-after-milliseconds越大园匹,代表Sentinel節(jié)點(diǎn)對(duì)于節(jié)點(diǎn)不可達(dá)的條件越寬松,反之越嚴(yán)格劫灶。
條件寬松有可能帶來的問題是節(jié)點(diǎn)確實(shí)不可達(dá)了裸违,那么應(yīng)用方需要等待故障轉(zhuǎn)移的時(shí)間越長,也就意味著應(yīng)用方故障時(shí)間可能越長本昏。
條件嚴(yán)格雖然可以及時(shí)發(fā)現(xiàn)故障完成故障轉(zhuǎn)移供汛,但是也存在一
定的誤判率。
配置down-after-milliseconds
雖然指定master-name涌穆,但實(shí)際上對(duì)Sentinel節(jié)點(diǎn)怔昨、主節(jié)點(diǎn)、從節(jié)點(diǎn)的失敗判定的超時(shí)時(shí)間都是這個(gè)值宿稀。
(3) parallel-syncs
sentinel parallel-syncs mymaster 1
當(dāng)Sentinel節(jié)點(diǎn)集合對(duì)主節(jié)點(diǎn)故障判定達(dá)成一致時(shí)趁舀,Sentinel領(lǐng)導(dǎo)者節(jié)點(diǎn)會(huì)做故障轉(zhuǎn)移操作,選出新的主節(jié)點(diǎn)祝沸,原來的從節(jié)點(diǎn)會(huì)向新的主節(jié)點(diǎn)發(fā)起復(fù)制操作矮烹,parallel-syncs就是用來限制在一次故障轉(zhuǎn)移之后越庇,每次向新的主節(jié)點(diǎn)發(fā)起復(fù)制操作的從節(jié)點(diǎn)個(gè)數(shù)。如果這個(gè)參數(shù)配置的比較大奉狈,那么多個(gè)從節(jié)點(diǎn)會(huì)向新的主節(jié)點(diǎn)同時(shí)發(fā)起復(fù)制操作卤唉,盡管復(fù)制操作通常不會(huì)阻塞主節(jié)點(diǎn),但是同時(shí)向主節(jié)點(diǎn)發(fā)起復(fù)制嘹吨,必然會(huì)對(duì)主節(jié)點(diǎn)所在的機(jī)器造成一定的網(wǎng)絡(luò)和磁盤IO開銷搬味。如果設(shè)置的這個(gè)值比較大,由于每個(gè)slave從新的master同步數(shù)據(jù)成功后才認(rèn)為故障轉(zhuǎn)移成功蟀拷,這里限制同時(shí)向新的master同步數(shù)據(jù)的slave個(gè)數(shù)碰纬,必然會(huì)導(dǎo)致故障轉(zhuǎn)移的時(shí)間邊長。
(4) sentinel failover-timeout
sentinel failover-timeout mymaster 180000
failover-timeout通常被解釋成故障轉(zhuǎn)移超時(shí)時(shí)間问芬,但實(shí)際上它作用于故障轉(zhuǎn)移的各個(gè)階段:
A. 選出合適從節(jié)點(diǎn)悦析。
B. 晉升選出的從節(jié)點(diǎn)為主節(jié)點(diǎn)。
C. 命令其余從節(jié)點(diǎn)復(fù)制新的主節(jié)點(diǎn)此衅。
D. 等待原主節(jié)點(diǎn)恢復(fù)后命令它去復(fù)制新的主節(jié)點(diǎn)强戴。
failover-timeout的作用具體體現(xiàn)在四個(gè)方面:
- 如果Redis Sentinel對(duì)一個(gè)主節(jié)點(diǎn)故障轉(zhuǎn)移失敗,那么下次再對(duì)該主節(jié)點(diǎn)做故障轉(zhuǎn)移的起始時(shí)間是failover-timeout的2倍挡鞍。
- 在B階段時(shí)骑歹,如果Sentinel節(jié)點(diǎn)向A階段選出來的從節(jié)點(diǎn)執(zhí)行
slaveof no one
一直失敗(例如該從節(jié)點(diǎn)此時(shí)出現(xiàn)故障)墨微,當(dāng)此過程超過failover-timeout時(shí)道媚,則故障轉(zhuǎn)移失敗。 - 在B階段如果執(zhí)行成功翘县,Sentinel節(jié)點(diǎn)還會(huì)執(zhí)行info命令來確認(rèn)A階段選出來的節(jié)點(diǎn)確實(shí)晉升為主節(jié)點(diǎn)最域,如果此過程執(zhí)行時(shí)間超過failovertimeout時(shí),則故障轉(zhuǎn)移失敗锈麸。
- 如果C階段執(zhí)行時(shí)間超過了failover-timeout(不包含復(fù)制時(shí)間)镀脂,則故障轉(zhuǎn)移失敗。注意即使超過了這個(gè)時(shí)間忘伞,Sentinel節(jié)點(diǎn)也會(huì)最終配置從節(jié)點(diǎn)去同步最新的主節(jié)點(diǎn)薄翅。
(5) auth-pass
# sentinel auth-pass mymaster redis
如果Sentinel監(jiān)控的主節(jié)點(diǎn)配置了密碼(redis.conf中的requirepass),sentinel auth-pass 配置通過添加主節(jié)點(diǎn)的密碼氓奈,防止Sentinel節(jié)點(diǎn)對(duì)主節(jié)點(diǎn)無法監(jiān)控匿刮。
(6) notification-script
# sentinel notification-script mymaster /tmp/xxx.sh
sentinel notification-script的作用是在故障轉(zhuǎn)移期間,當(dāng)一些警告級(jí)別的Sentinel事件發(fā)生(指重要事件探颈,例如-sdown:客觀下線、-odown:主觀下線)時(shí)训措,會(huì)觸發(fā)對(duì)應(yīng)路徑的腳本伪节,并向腳本發(fā)送相應(yīng)的事件參數(shù)光羞。這些腳本利用這些參數(shù)作為郵件或者短信報(bào)警依據(jù)。
(7) client-reconfig-script
# sentinel client-reconfig-script mymaster /tmp/xxx.sh
sentinel client-reconfig-script的作用是在故障轉(zhuǎn)移結(jié)束后怀大,會(huì)觸發(fā)對(duì)應(yīng)路徑的腳本纱兑,并向腳本發(fā)送故障轉(zhuǎn)移結(jié)果的相關(guān)參數(shù)。和notification-script類似化借,設(shè)置的腳本會(huì)接收每個(gè)Sentinel節(jié)點(diǎn)傳過來的故障轉(zhuǎn)移結(jié)果參數(shù)潜慎,并觸發(fā)類似短信和郵件報(bào)警。
當(dāng)故障轉(zhuǎn)移結(jié)束蓖康,每個(gè)Sentinel節(jié)點(diǎn)可以將故障轉(zhuǎn)移的結(jié)果發(fā)送給對(duì)應(yīng)的腳本铐炫,具體參數(shù)如下:
<master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
- <master-name>:主節(jié)點(diǎn)名。
- <role>:Sentinel節(jié)點(diǎn)的角色蒜焊,分別是leader和observer倒信,leader代表當(dāng)前Sentinel節(jié)點(diǎn)是領(lǐng)導(dǎo)者,是它進(jìn)行的故障轉(zhuǎn)移泳梆;observer是其余Sentinel節(jié)點(diǎn)鳖悠。
- <from-ip>:原主節(jié)點(diǎn)的ip地址。
- <from-port>:原主節(jié)點(diǎn)的端口优妙。
- <to-ip>:新主節(jié)點(diǎn)的ip地址乘综。
- <to-port>:新主節(jié)點(diǎn)的端口。
有關(guān)sentinel notification-script和sentinel client-reconfig-script有幾點(diǎn)需要注意:
- <script-path>必須有可執(zhí)行權(quán)限套硼。
- <script-path>開頭必須包含shell腳本頭(例如#!/bin/sh)卡辰,否則事件發(fā)生時(shí)Redis將無法執(zhí)行腳本。
- Redis規(guī)定腳本的最大執(zhí)行時(shí)間不能超過60秒熟菲,超過后腳本將被殺掉看政。
- 如果shell腳本以exit 1結(jié)束,那么腳本稍后重試執(zhí)行抄罕。如果以exit 2或者更高的值結(jié)束允蚣,那么腳本不會(huì)重試。正常返回值是exit 0呆贿。
- 如果需要運(yùn)維的Redis Sentinel比較多嚷兔,建議不要使用這種腳本的形式來進(jìn)行通知,這樣會(huì)增加部署的成本做入。
3. Redis Sentinel 啟動(dòng)日志分析
(1) sentinel.conf 的變化
啟動(dòng)之前冒晰,sentinel_26379.conf中的內(nèi)容如下:
bind node01
port 26379
daemonize yes
dir /home/hadoop/data/redis/26379
logfile /home/hadoop/logs/redis/26379/sentinel_26379.log
sentinel monitor mymaster node01 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
啟動(dòng)之后,文件內(nèi)容變?yōu)椋?/p>
bind node01
port 26379
daemonize yes
dir "/home/hadoop/data/redis/26379"
logfile "/home/hadoop/logs/redis/26379/sentinel_26379.log"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.239.101 6379 2
sentinel config-epoch mymaster 0
sentinel current-epoch 0
sentinel myid 8a692e7438e7086c98e3fafbb72337e21ada032d
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 192.168.239.103 6379
sentinel known-slave mymaster 192.168.239.102 6379
sentinel known-sentinel mymaster 192.168.239.103 26379 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4
sentinel known-sentinel mymaster 192.168.239.102 26379 42b932cf4f1a5bc53f5cde7275f9ae0da1026057
變化是:
- 去掉了一些默認(rèn)配置竟块,例如parallel-syncs壶运、failover-timeout。
- 添加了配置版本相關(guān)參數(shù)浪秘。
(2) 故障轉(zhuǎn)移日志分析
- 查看 master 信息
[hadoop@node01 redis-4.0.12]$ redis-cli -h node01 -p 26379
node01:26379> sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "192.168.239.101"
5) "port"
6) "6379"
7) "runid"
8) "ecce013361abe093768ef647cfee7ad5f058e73b"
......
- 殺死 master 節(jié)點(diǎn)的 redis 服務(wù)
[hadoop@node01 redis-4.0.12]$ ps -ef | grep redis
hadoop 7139 1 0 08:58 ? 00:00:08 redis-server node01:6379
hadoop 7363 1 0 09:10 ? 00:00:08 redis-sentinel node01:26379 [sentinel]
hadoop 7431 7042 0 10:15 pts/0 00:00:00 grep --color=auto redis
[hadoop@node01 redis-4.0.12]$ kill -9 7139
- 查看 master 日志
# 這些日志都是啟動(dòng) master 后打印的
# kill 掉 master 進(jìn)程后沒有打印任何日志
7139:M 28 Feb 08:58:31.656 * Starting BGSAVE for SYNC with target: disk
7139:M 28 Feb 08:58:31.656 * Background saving started by pid 7146
7146:C 28 Feb 08:58:31.658 * DB saved on disk
7146:C 28 Feb 08:58:31.658 * RDB: 4 MB of memory used by copy-on-write
7139:M 28 Feb 08:58:31.690 * Background saving terminated with success
7139:M 28 Feb 08:58:31.690 * Synchronization with slave 192.168.239.103:6379 succeeded
# 由于是使用 kill 的方式殺死 master 進(jìn)程
# 所以 master 直接斷開蒋情,沒有做任何的數(shù)據(jù)持久化
- 查看node02節(jié)點(diǎn)(slave)的日志
# 與 master 斷開連接
6845:S 28 Feb 10:15:15.702 # Connection with master lost.
# 緩存失聯(lián)的 master 狀態(tài)信息
6845:S 28 Feb 10:15:15.702 * Caching the disconnected master state.
6845:S 28 Feb 10:15:16.239 * Connecting to MASTER 192.168.239.101:6379
6845:S 28 Feb 10:15:16.240 * MASTER <-> SLAVE sync started
# 請求與 master 同步數(shù)據(jù)失敗
6845:S 28 Feb 10:15:16.240 # Error condition on socket for SYNC: Connection refused
# node02 節(jié)點(diǎn)將升級(jí)為 master
......
# 清除舊的 master 的狀態(tài)信息
6845:M 28 Feb 10:15:46.131 * Discarding previously cached master state.
# node02 提升為 master
6845:M 28 Feb 10:15:46.131 * MASTER MODE enabled (user request from 'id=15 addr=192.168.239.103:34822 fd=12 name=sentinel-94b8a016-cmd age=3949 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=0 qbuf-free=32768 obl=36 oll=0 omem=0 events=r cmd=exec')
# 重寫配置
6845:M 28 Feb 10:15:46.132 # CONFIG REWRITE executed with success.
# node03節(jié)點(diǎn)請求從node02節(jié)點(diǎn)復(fù)制數(shù)據(jù)
Slave 192.168.239.103:6379 asks for synchronization
# node02 節(jié)點(diǎn)同意了數(shù)據(jù)同步的請求埠况,這兩個(gè)節(jié)點(diǎn)成功同步數(shù)據(jù)
6845:M 28 Feb 10:15:47.134 * Partial resynchronization request from 192.168.239.103:6379 accepted. Sending 458 bytes of backlog starting from offset 970803.
- 查看node03節(jié)點(diǎn)(slave)的日志
# 與 master node01 失聯(lián)
6607:S 28 Feb 10:15:15.708 # Connection with master lost.
6607:S 28 Feb 10:15:15.708 * Caching the disconnected master state.
6607:S 28 Feb 10:15:15.953 * Connecting to MASTER 192.168.239.101:6379
6607:S 28 Feb 10:15:15.953 * MASTER <-> SLAVE sync started
6607:S 28 Feb 10:15:15.954 # Error condition on socket for SYNC: Connection refused
......
# 新的 master:node02:6379 準(zhǔn)備就緒
6607:S 28 Feb 10:15:46.910 * SLAVE OF 192.168.239.102:6379 enabled (user request from 'id=15 addr=192.168.239.103:33915 fd=12 name=sentinel-94b8a016-cmd age=3949 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=145 qbuf-free=32623 obl=36 oll=0 omem=0 events=r cmd=exec')
# 重寫配置
6607:S 28 Feb 10:15:46.910 # CONFIG REWRITE executed with success.
# 連接到新的 master
6607:S 28 Feb 10:15:47.139 * Connecting to MASTER 192.168.239.102:6379
# 開始從新的 master 同步數(shù)據(jù)
6607:S 28 Feb 10:15:47.139 * MASTER <-> SLAVE sync started
6607:S 28 Feb 10:15:47.139 * Non blocking connect for SYNC fired the event.
# 新master 回復(fù)了 slave 的ping命令
6607:S 28 Feb 10:15:47.139 * Master replied to PING, replication can continue...
6607:S 28 Feb 10:15:47.140 * Trying a partial resynchronization (request 48288f005d4b8d4420c2d5081cb640081600e525:970803).
# 成功發(fā)送同步數(shù)據(jù)請求
6607:S 28 Feb 10:15:47.140 * Successful partial resynchronization with master.
6607:S 28 Feb 10:15:47.140 # Master replication ID changed to 907b3e69f9e1ae789481c524f285834ea4d55445
# master 接受了 同步數(shù)據(jù)請求
6607:S 28 Feb 10:15:47.140 * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.
- 在sentinel.conf中查看每個(gè)節(jié)點(diǎn)的 sentinel ID
# node01
sentinel myid 8a692e7438e7086c98e3fafbb72337e21ada032d
# node02
sentinel myid 42b932cf4f1a5bc53f5cde7275f9ae0da1026057
# node03
sentinel myid 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4
- 查看 sentinel-0 日志
# 確認(rèn) node01 主觀下線
7363:X 28 Feb 10:15:45.795 # +sdown master mymaster 192.168.239.101 6379
# 更新配置版本為2
7363:X 28 Feb 10:15:45.892 # +new-epoch 2
# # node03 請求成為leader,開始投票
7363:X 28 Feb 10:15:45.893 # +vote-for-leader 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 2
# node03 成為leader棵癣,從leader更新配置
7363:X 28 Feb 10:15:46.905 # +config-update-from sentinel 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 192.168.239.103 26379 @ mymaster 192.168.239.101 6379
# 從 leader 那里得到的新的主從架構(gòu)信息如下:
# master 從 node01 切換為 node02
7363:X 28 Feb 10:15:46.905 # +switch-master mymaster 192.168.239.101 6379 192.168.239.102 6379
# node03 成為 node02 的 slave
7363:X 28 Feb 10:15:46.905 * +slave slave 192.168.239.103:6379 192.168.239.103 6379 @ mymaster 192.168.239.102 6379
# node01 成為 node02 的 slave
7363:X 28 Feb 10:15:46.905 * +slave slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
# node01 這個(gè) slave 主觀下線(因?yàn)?node01 還沒啟動(dòng))
7363:X 28 Feb 10:16:16.942 # +sdown slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
- 查看 sentinel-1 日志
# 確認(rèn) master 主觀下線
6961:X 28 Feb 10:15:45.851 # +sdown master mymaster 192.168.239.101 6379
# 更新配置版本為2
6961:X 28 Feb 10:15:45.891 # +new-epoch 2
# node03請求成為leader辕翰,開始投票
6961:X 28 Feb 10:15:45.892 # +vote-for-leader 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 2
# 確認(rèn) master 客觀下線
6961:X 28 Feb 10:15:45.909 # +odown master mymaster 192.168.239.101 6379 #quorum 3/2
6961:X 28 Feb 10:15:45.909 # Next failover delay: I will not start a failover before Thu Feb 28 10:21:46 2019
# 從 node03(leader) 更新配置
6961:X 28 Feb 10:15:46.904 # +config-update-from sentinel 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 192.168.239.103 26379 @ mymaster 192.168.239.101 6379
# 得到的新的主從架構(gòu)關(guān)系如下:
# master 從 node01 切換為 node02
6961:X 28 Feb 10:15:46.904 # +switch-master mymaster 192.168.239.101 6379 192.168.239.102 6379
# node03 成為 node02 的 slave
6961:X 28 Feb 10:15:46.904 * +slave slave 192.168.239.103:6379 192.168.239.103 6379 @ mymaster 192.168.239.102 6379
# node01 成為 node02 的 slave
6961:X 28 Feb 10:15:46.904 * +slave slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
# node01 這個(gè) slave 主觀下線(因?yàn)?node01 還沒啟動(dòng)
6961:X 28 Feb 10:16:16.928 # +sdown slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
- 查看 sentinel-2 日志
# 確認(rèn) node01 主觀下線
6846:X 28 Feb 10:15:45.842 # +sdown master mymaster 192.168.239.101 6379
# 確認(rèn) node01 客觀下線
# 這里也可以看出,誰先確認(rèn) master 客觀下線狈谊,誰就會(huì)先申請成為故障轉(zhuǎn)移的 leader
# 而先申請的就會(huì)成為 leader
6846:X 28 Feb 10:15:45.895 # +odown master mymaster 192.168.239.101 6379 #quorum 2/2
# 更新配置版本
6846:X 28 Feb 10:15:45.895 # +new-epoch 2
# 嘗試進(jìn)行故障轉(zhuǎn)移
6846:X 28 Feb 10:15:45.895 # +try-failover master mymaster 192.168.239.101 6379
# 開啟為 node03 投票
6846:X 28 Feb 10:15:45.896 # +vote-for-leader 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 2
# 得到 node01 投的一票
6846:X 28 Feb 10:15:45.898 # 8a692e7438e7086c98e3fafbb72337e21ada032d voted for 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 2
# 得到 node02 投的一票
6846:X 28 Feb 10:15:45.899 # 42b932cf4f1a5bc53f5cde7275f9ae0da1026057 voted for 94b8a0165d93e9ad8288f0a77a855b59a6c5fab4 2
# 當(dāng)選為執(zhí)行故障轉(zhuǎn)移的 leader
6846:X 28 Feb 10:15:45.997 # +elected-leader master mymaster 192.168.239.101 6379
6846:X 28 Feb 10:15:45.997 # +failover-state-select-slave master mymaster 192.168.239.101 6379
# 選擇 node02 成為新的 master
6846:X 28 Feb 10:15:46.074 # +selected-slave slave 192.168.239.102:6379 192.168.239.102 6379 @ mymaster 192.168.239.101 6379
# 讓 node02 執(zhí)行 slaveof-noone 命令
6846:X 28 Feb 10:15:46.074 * +failover-state-send-slaveof-noone slave 192.168.239.102:6379 192.168.239.102 6379 @ mymaster 192.168.239.101 6379
# 等待 node02 成為 master
6846:X 28 Feb 10:15:46.137 * +failover-state-wait-promotion slave 192.168.239.102:6379 192.168.239.102 6379 @ mymaster 192.168.239.101 6379
# 確認(rèn) node02 成為 master
6846:X 28 Feb 10:15:46.858 # +promoted-slave slave 192.168.239.102:6379 192.168.239.102 6379 @ mymaster 192.168.239.101 6379
# 重新配置 slave
6846:X 28 Feb 10:15:46.858 # +failover-state-reconf-slaves master mymaster 192.168.239.101 6379
# 讓 node03 去復(fù)制 node02
6846:X 28 Feb 10:15:46.909 * +slave-reconf-sent slave 192.168.239.103:6379 192.168.239.103 6379 @ mymaster 192.168.239.101 6379
# node03 復(fù)制 node02 過程進(jìn)行中
6846:X 28 Feb 10:15:47.874 * +slave-reconf-inprog slave 192.168.239.103:6379 192.168.239.103 6379 @ mymaster 192.168.239.101 6379
# node03 復(fù)制 node02 完成
6846:X 28 Feb 10:15:47.874 * +slave-reconf-done slave 192.168.239.103:6379 192.168.239.103 6379 @ mymaster 192.168.239.101 6379
# 故障轉(zhuǎn)移結(jié)束
6846:X 28 Feb 10:15:47.965 # +failover-end master mymaster 192.168.239.101 6379
# 發(fā)布消息喜命,包括切換了 master,主從架構(gòu)的變化等信息
6846:X 28 Feb 10:15:47.965 # +switch-master mymaster 192.168.239.101 6379 192.168.239.102 6379
6846:X 28 Feb 10:15:47.965 * +slave slave 192.168.239.103:6379 192.168.239.103 6379 @ mymaster 192.168.239.102 6379
6846:X 28 Feb 10:15:47.965 * +slave slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
6846:X 28 Feb 10:16:18.048 # +sdown slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
- 啟動(dòng)node01節(jié)點(diǎn)的redis服務(wù)
[hadoop@node01 redis-4.0.12]$ redis-server ./redis_6379.conf
- node01的redis服務(wù)日志
# 連接到新的master node02
7471:S 28 Feb 11:46:12.693 * Connecting to MASTER 192.168.239.102:6379
# 開始從 node02 復(fù)制數(shù)據(jù)
7471:S 28 Feb 11:46:12.693 * MASTER <-> SLAVE sync started
......
# 復(fù)制成功
7471:S 28 Feb 11:47:03.170 * Background saving terminated with success
- node02的redis服務(wù)日志
# node01 請求同步數(shù)據(jù)
6845:M 28 Feb 10:15:47.134 * Slave 192.168.239.103:6379 asks for synchronization
6845:M 28 Feb 10:15:47.134 * Partial resynchronization request from 192.168.239.103:6379 accepted. Sending 458 bytes of backlog starting from offset 970803.
6845:M 28 Feb 11:46:12.693 * Slave 192.168.239.101:6379 asks for synchronization
6845:M 28 Feb 11:46:12.693 * Partial resynchronization not accepted: Replication ID mismatch (Slave asked for '3c646f5c318f604379978850ffefd54372e5218c', my replication IDs are '907b3e69f9e1ae789481c524f285834ea4d55445' and '48288f005d4b8d4420c2d5081cb640081600e525')
# 開始同步數(shù)據(jù)
6845:M 28 Feb 11:46:12.693 * Starting BGSAVE for SYNC with target: disk
6845:M 28 Feb 11:46:12.694 * Background saving started by pid 7055
7055:C 28 Feb 11:46:12.804 * DB saved on disk
7055:C 28 Feb 11:46:12.804 * RDB: 6 MB of memory used by copy-on-write
6845:M 28 Feb 11:46:12.904 * Background saving terminated with success
# 同步數(shù)據(jù)成功
6845:M 28 Feb 11:46:12.904 * Synchronization with slave 192.168.239.101:6379 succeeded
- node03的redis服務(wù)日志
# node03 沒有產(chǎn)生新日志
- sentinel 日志(3臺(tái)節(jié)點(diǎn)新增的日志都一樣)
# 不再認(rèn)為 node01 主觀下線
6846:X 28 Feb 11:46:02.752 # -sdown slave 192.168.239.101:6379 192.168.239.101 6379 @ mymaster 192.168.239.102 6379
4. 其他 Redis Sentinel 的知識(shí)點(diǎn)
(1) 監(jiān)控多個(gè) master
Redis Sentinel可以同時(shí)監(jiān)控多個(gè)主節(jié)點(diǎn)河劝,具體拓?fù)鋱D類似于下圖:
配置方法也比較簡單壁榕,只需要指定多個(gè)master-name來區(qū)分不同的主節(jié)點(diǎn)即可,例如下面的配置監(jiān)控master-1(node01:6379)和master-2(node04:6379)兩個(gè)主節(jié)點(diǎn):
sentinel monitor master-1 node01 6379 2
sentinel down-after-milliseconds master-1 60000
sentinel failover-timeout master-1 180000
sentinel parallel-syncs master-1 1
sentinel monitor master-2 node04 6379 2
sentinel down-after-milliseconds master-2 10000
sentinel failover-timeout master-2 180000
sentinel parallel-syncs master-2 1
(2) 動(dòng)態(tài)設(shè)置參數(shù)
Sentinel節(jié)點(diǎn)支持動(dòng)態(tài)地設(shè)置參數(shù)丧裁,但并不是支持所有的參數(shù)护桦,具體使用方法如下:
sentinel set <param> <value>
參數(shù) | 使用方法 |
---|---|
quorum | sentinel set mymaster quorum 2 |
down-after-milliseconds | sentinel set mymaster down-after-milliseconds 30000 |
parallel-syncs | sentinel set mymaster parallel-syncs 1 |
failover-timeout | sentinel set mymaster failover-timeout 180000 |
auth-pass | sentinel set mymaster auth-pass xxx |
notification-script | sentinel set mymaster notification-script /path/xxx.sh |
client-reconfig-script | sentinel set mymaster client-reconfig-script /path/xxx.sh |
注意點(diǎn):
- sentinel set命令只對(duì)當(dāng)前Sentinel節(jié)點(diǎn)有效。
- sentinel set命令如果執(zhí)行成功會(huì)立即刷新配置文件煎娇,這點(diǎn)和Redis普通數(shù)據(jù)節(jié)點(diǎn)設(shè)置配置需要執(zhí)行config rewrite刷新到配置文件不同二庵。
- 建議所有Sentinel節(jié)點(diǎn)的配置盡可能一致,這樣在故障發(fā)現(xiàn)和轉(zhuǎn)移時(shí)比較容易達(dá)成一致缓呛。
- Sentinel對(duì)外不支持config命令催享。
(3) Redis Sentinel 部署建議
Sentinel節(jié)點(diǎn)不應(yīng)該部署在一臺(tái)物理機(jī)器上。這里特意強(qiáng)調(diào)物理機(jī)是因?yàn)橐慌_(tái)物理機(jī)做成了若干虛擬機(jī)或者現(xiàn)今比較流行的容器哟绊,它們雖然有不同的IP地址因妙,但實(shí)際上它們都是同一臺(tái)物理機(jī),同一臺(tái)物理機(jī)意味著如果這臺(tái)機(jī)器有什么硬件故障票髓,所有的虛擬機(jī)都會(huì)受到影響攀涵,為了實(shí)現(xiàn)Sentinel節(jié)點(diǎn)集合真正的高可用,請勿將Sentinel節(jié)點(diǎn)部署在同一臺(tái)物理機(jī)器上洽沟。
部署至少三個(gè)且奇數(shù)個(gè)的Sentinel節(jié)點(diǎn)以故。3個(gè)以上是通過增加Sentinel節(jié)點(diǎn)的個(gè)數(shù)提高對(duì)于故障判定的準(zhǔn)確性,因?yàn)轭I(lǐng)導(dǎo)者選舉需要至少一半加1個(gè)節(jié)點(diǎn)裆操,奇數(shù)個(gè)節(jié)點(diǎn)在相同容錯(cuò)性的基礎(chǔ)上可以節(jié)省一個(gè)節(jié)點(diǎn)怒详。這里怎么理解可以節(jié)省1個(gè)節(jié)點(diǎn)?
3個(gè)節(jié)點(diǎn)踪区,要求 3/2 + 1 = 1 + 1 = 2 個(gè)sentinel節(jié)點(diǎn)同時(shí)在線才可以選舉 leader昆烁,也就是說最多允許1個(gè)sentinel掛掉。
4個(gè)節(jié)點(diǎn)缎岗,要求 4/2 + 1 = 2 + 1 = 3個(gè)sentinel節(jié)點(diǎn)同時(shí)在線才可以選舉 leader静尼,也就是說最多允許1個(gè)sentinel掛掉。
也就是說,3個(gè)節(jié)點(diǎn)和4個(gè)節(jié)點(diǎn)都是最多允許1個(gè)節(jié)點(diǎn)掛掉鼠渺,那么他們的容錯(cuò)性相同蜗元,但是3個(gè)節(jié)點(diǎn)就是可以節(jié)省1個(gè)節(jié)點(diǎn)來達(dá)到相同的容錯(cuò)性。多套redis主從架構(gòu)使用一套 sentinel 集群進(jìn)行監(jiān)控還是多套 sentinel 集群進(jìn)行監(jiān)控系冗?
方案一:一套Sentinel,很明顯這種方案在一定程度上降低了維護(hù)成本薪鹦,因?yàn)橹恍枰S護(hù)固定個(gè)數(shù)的Sentinel節(jié)點(diǎn)掌敬,集中對(duì)多個(gè)Redis數(shù)據(jù)節(jié)點(diǎn)進(jìn)行管理就可以了。但是這同時(shí)也是它的缺點(diǎn)池磁,如果這套Sentinel節(jié)點(diǎn)集合出現(xiàn)異常奔害,可能會(huì)對(duì)多個(gè)Redis數(shù)據(jù)節(jié)點(diǎn)造成影響。還有如果監(jiān)控的Redis數(shù)據(jù)節(jié)點(diǎn)較多地熄,會(huì)造成Sentinel節(jié)點(diǎn)產(chǎn)生過多的網(wǎng)絡(luò)連接华临,也會(huì)有一定的影響。
方案二:多套Sentinel端考,顯然這種方案的優(yōu)點(diǎn)和缺點(diǎn)和上面是相反的雅潭,每個(gè)Redis主節(jié)點(diǎn)都有自己的Sentinel節(jié)點(diǎn)集合,會(huì)造成資源浪費(fèi)却特。但是優(yōu)點(diǎn)也很明顯扶供,每套R(shí)edis Sentinel都是彼此隔離的。
建議:
如果Sentinel節(jié)點(diǎn)集合監(jiān)控的是同一個(gè)業(yè)務(wù)的多個(gè)主節(jié)點(diǎn)集合裂明,那么使用方案一椿浓,否則一般建議采用方案二。
(4) Redis Sentinel 運(yùn)維
<1> 更換主節(jié)點(diǎn)
執(zhí)行以下命令:
sentinel failover <master-name>
# 例如
sentinel failover mymaster
如果想切換到指定的某臺(tái)從節(jié)點(diǎn)上闽晦,那么需要先把其他的從節(jié)點(diǎn)的 priority 設(shè)置為0(設(shè)置為0扳碍,代表禁止該節(jié)點(diǎn)成為主節(jié)點(diǎn)),當(dāng)切換成功后仙蛉,再把其他從節(jié)點(diǎn)的 priority 復(fù)原即可笋敞。
<2> 增加 slave
在新加的 slave 的 redis.conf 文件中添加slaveof [master-ip] [master-port]
的配置,使用redis-server
啟動(dòng)即可捅儒,它將被Sentinel節(jié)點(diǎn)自動(dòng)發(fā)現(xiàn)液样。
<3> slave 下線
- 臨時(shí)下線
臨時(shí)下線只需要關(guān)閉某個(gè)從節(jié)點(diǎn)的redis服務(wù)即可。臨時(shí)下線后巧还,sentinel節(jié)點(diǎn)還是會(huì)監(jiān)控這個(gè)已下線的從節(jié)點(diǎn)鞭莽。 - 永久下線
永久下線首先關(guān)閉從節(jié)點(diǎn)的服務(wù),然后讓sentinel集群不再監(jiān)控該節(jié)點(diǎn)麸祷。因?yàn)槎ㄆ诒O(jiān)控也會(huì)造成一定的網(wǎng)絡(luò)資源浪費(fèi)澎怒,sentinel更新監(jiān)控節(jié)點(diǎn)的命令為:
sentinel reset master-name
<4> 增加 sentinel 節(jié)點(diǎn)
在新加的 sentinel 節(jié)點(diǎn)的 sentinel.conf 文件中設(shè)置sentinel monitor
和其他配置,使用redis-sentinel啟動(dòng)即可,它將被其余sentinel節(jié)點(diǎn)自動(dòng)發(fā)現(xiàn)喷面。
<5> sentinel 節(jié)點(diǎn)下線
與 slave 下線一樣星瘾,如果是臨時(shí)下線,關(guān)閉服務(wù)即可惧辈。如果是永久下線琳状,關(guān)閉服務(wù)后執(zhí)行sentinel reset [master-name]
命令。