redis主從復(fù)制原理
redis主從復(fù)制分為全量同步和增量同步,首次同步是全量同步,主從同步可以讓從服務(wù)器從主服務(wù)器備份數(shù)據(jù), 而且從服務(wù)還可以作為其他從節(jié)點提供數(shù)據(jù)同步,redis的主從同步是非阻塞的,redis master收到slave服務(wù)器的sync命令會fork一個子進程在后臺執(zhí)行bgsave命令,并將新寫入的數(shù)據(jù)寫入到一個緩存區(qū)里,bgsave執(zhí)行完成之后并將生成的RDB文件發(fā)送給slave,slave將收到的RDB載入自己的內(nèi)存,然后redis master將自己緩存區(qū)中的內(nèi)容在全部發(fā)送給slave,之后的同步slave服務(wù)器會發(fā)送一個offset的位置(類似于mysql的binlog位置)給redis master, 主服務(wù)器檢查后位置沒有錯誤,將此位置之后的數(shù)據(jù)包括寫在緩沖區(qū)的積壓數(shù)據(jù)發(fā)送redis slave,slave將主服務(wù)器發(fā)送的積壓數(shù)據(jù)寫入內(nèi)存,這樣一次完整的數(shù)據(jù)同步就完成了。之后在同步的時候slave只要發(fā)送當前的offset位置給mater,然后master根據(jù)響應(yīng)的位置將之后的數(shù)據(jù)發(fā)送給slave保存到期內(nèi)存中。
redis全量復(fù)制一般發(fā)生在slave初始化階段,這時slave需要將master節(jié)點上的所有數(shù)據(jù)都復(fù)制一份。過程如下:
1)slave服務(wù)器連接master服務(wù)器,發(fā)送SYNC命令;
2)master節(jié)點接收到SYNC命令后,fork一個字進程開始執(zhí)行BGSAVE命令生產(chǎn)RDB快照文件并使用緩沖區(qū)記錄被執(zhí)行的寫命令。
3)master服務(wù)器BGSAVE執(zhí)行完成后,向所有slave服務(wù)器發(fā)送快照文件,并在發(fā)送期間繼續(xù)記錄被執(zhí)行的寫命令;
4)slave節(jié)點收到RDB快照文件后丟棄當前節(jié)點所有舊數(shù)據(jù),載入收到的RDB快照文件。
5)master快照發(fā)送完成后開始向slave節(jié)點發(fā)送緩沖區(qū)中的寫命令。
6)slave節(jié)點完成快照的載入,開始接收命令請求,并執(zhí)行來自master緩沖區(qū)的寫命令。
7)后期同步會先發(fā)送自己slave_repl_offset位置,只同步新增加的數(shù)據(jù),不在全量同步。
192.168.2.239 redis master sentinel s1
192.168.2.240 redis slave1 sentinel s2
192.168.2.241 redis slave2 sentinel s3
1、配置redis主
vim /data/app/redis/etc/redis.conf
requirepass password
bind 192.168.2.239
loggile "/data/app/redis/logs/redis.log"
replicaof 192.168.2.239 6379
masterauth <master-password>
2、配置redis從(多個從節(jié)點配置方法相同)
vim /data/app/redis/etc/redis.conf
requirepass password
bind 192.168.2.240
replicaof 192.168.2.239 6379
masterauth <master-password>
loggile "/data/app/redis/logs/redis.log"
登錄從節(jié)點redis查看slave狀態(tài)
redis-cli -h 192.168.2.240 -p 6379 -a password
INOF Replication


3、驗證主從數(shù)據(jù)同步
redis master添加數(shù)據(jù)

redis slave查看數(shù)據(jù)同步情況


集群搭建后添加數(shù)據(jù)提示“沒有分配槽”錯誤修復(fù)方法

redis-cli --cluster fix 192.168.2.239:6379 -a password
注意事項:
不同版本的redis之間存在兼容性問題,在搭建redis集群時各節(jié)點的redis版本必須保持一致。
基于sentinel(哨兵)搭建redis高可用集群
sentinel進程是用于監(jiān)控redis集群中master服務(wù)的工作狀態(tài),在master服務(wù)發(fā)生故障時,可以實現(xiàn)master和slave服務(wù)器角色的切換,以此保證redis服務(wù)的高可用。
sentinel是一個分布式系統(tǒng),可以在一個機構(gòu)中運行多個sentinel進程,該進程使用流言協(xié)議(gossip protocols)來接收關(guān)于master是否在下線的消息,如果master下線則使用投票協(xié)議(Agreement Protocols)來決定是否執(zhí)行自動故障遷移,以及選擇哪個slave作為新的master。集群中的每個sentinel進程會向其他的sentinel、master、slave定時發(fā)送消息,已確認對方是否存活,如果發(fā)現(xiàn)對方在指定配置時間內(nèi)未得到響應(yīng),則暫時任務(wù)對方已下線,這就是所謂的“主觀認為宕機”。
主觀是每個成員都具有的獨自的而且可能相同也可能不同的意識(subjective sown)簡稱SDOWN。
當sentinel集群中多數(shù)sentinel進程在對master主服務(wù)器做出down的判斷,并且通過sentinel is-master-down-by-addr命令互相交流之后,得出的master server下線判斷,這種方式就是“客觀宕機”,客觀是不依賴與某種意識而已經(jīng)實際存在的一切事物(objectively down)簡稱ODOWN。
通過一定的vote算法,從剩下的slave從服務(wù)器節(jié)點中,選取一臺提升為master,然后自動修改redis.conf sentinel.conf的相關(guān)配置,并開啟故障轉(zhuǎn)移。
當故障的redis master恢復(fù)后sentinel會將其作為slave角色加入集群中。
使用已搭建好的redis主從架構(gòu)
1、192.168.2.239 redis主,sentinel server1配置
將源碼目錄下的sentinel配置文件復(fù)制redis程序目錄的etc目錄下
cp sentinel.conf /data/app/redis/etc/
修改sentinel配置文件
vim /data/app/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes
pidfile /data/app/redis/run/redis-sentinel.pid
logfile "/data/app/redis/logs/sentinel.log"
dir /data/app/redis
#法定人數(shù)限制(quorum),即有幾個slave認為master down了就進行故障轉(zhuǎn)移
sentinel monitor mymaster 192.168.2.239 6379 2
sentinel auth-pass mymaster 123456
#(SDOWN)主觀下線的時間
sentinel down-after-milliseconds mymaster 30000
#發(fā)送故障轉(zhuǎn)移同時向新master同步數(shù)據(jù)的slave數(shù)量,數(shù)字越小同步時間越長
sentinel parallel-syncs mymaster 1
#所有的slave指向新的master所需的超時時間
sentinel failover-timeout mymaster 180000
#禁止修改腳本
sentinel deny-scripts-reconfig yes
2、192.168.2.240 redis slave1,sentinel server2配置
vim /data/app/redis/etc/sentinel.conf
bind 192.168.2.240
port 26379
daemonize yes
pidfile /data/app/redis/run/redis-sentinel.pid
logfile "/data/app/redis/logs/sentinel.log"
dir /data/app/redis
#法定人數(shù)限制(quorum),即有幾個slave認為master down了就進行故障轉(zhuǎn)移
sentinel monitor mymaster 192.168.2.239 6379 2
sentinel auth-pass mymaster 123456
#禁止修改腳本
sentinel deny-scripts-reconfig yes
3、192.168.2.241 redis slave2,sentinel server2配置
vim /data/app/redis/etc/sentinel.conf
bind 192.168.2.241
port 26379
daemonize yes
pidfile /data/app/redis/run/redis-sentinel.pid
logfile "/data/app/redis/logs/sentinel.log"
dir /data/app/redis
#法定人數(shù)限制(quorum),即有幾個slave認為master down了就進行故障轉(zhuǎn)移
sentinel monitor mymaster 192.168.2.239 6379 2
sentinel auth-pass mymaster 123456
#禁止修改腳本
sentinel deny-scripts-reconfig yes
4、在所有節(jié)點上啟動sentinel服務(wù)
/data/app/redis/bin/redis-sentinel /data/app/redis/etc/sentinel.conf
查看sentinel server1的日志

5、查看sentinel狀態(tài),停止redis master測試故障轉(zhuǎn)移
redis-cli -h 192.168.2.239 -p 26379

停止redis master服務(wù),查看集群信息
systemctl stop redis
查看sentinel日志,redis master由192.168.2.239切換為192.168.2.240

查看192.168.2.240角色狀態(tài)和日志,240節(jié)點由redis slave切換至master
redis-cli -h 192.168.2.240 -p 6379


(切換的過程中sentinel會修改redis.conf sentinel.conf配置文件)