Redis主從復(fù)制
一、什么是主從復(fù)制
主從復(fù)制是指用戶可以搭建多個(gè)服務(wù)器,其中幾個(gè)服務(wù)器當(dāng)做主服務(wù)器,提供寫功能。其余的服務(wù)器當(dāng)做從服務(wù)器,提供讀功能。每當(dāng)主服務(wù)器收到寫請求時(shí),同時(shí)需要把數(shù)據(jù)發(fā)送給從服務(wù)器。保證主從服務(wù)器的數(shù)據(jù)保持最終一致性。利用這個(gè)機(jī)制,可以利用廉價(jià)的服務(wù)器搭建高可用,高并發(fā)集群。主從復(fù)制是搭建高可用集群的必備利器。
二、Redis怎么實(shí)現(xiàn)主從復(fù)制
2.1 slaveof
在Redis中可以使用slaveof命令讓一個(gè)Redis實(shí)例去復(fù)制另一個(gè)Redis實(shí)例的內(nèi)容。這里需要注意當(dāng)A實(shí)例執(zhí)行該命令去復(fù)制B實(shí)例的內(nèi)容后,以前A實(shí)例的內(nèi)容都將被B實(shí)例的內(nèi)容覆蓋。同時(shí)在從服務(wù)器將被設(shè)置為只讀,向從服務(wù)器發(fā)送寫命令時(shí),將被拒絕。(也可以在redis.conf中配置該命令,啟動時(shí)就發(fā)起主從同步)
2.2 主從復(fù)制的原理V1
當(dāng)從服務(wù)器發(fā)起slaveof命令后,主從服務(wù)器之間通過TCP長連接進(jìn)行通信,主要是以下步驟:

第一次完整的主從同步就完成了。然后主從之間會維持TCP連接,每次master收到新的寫命令后,都會發(fā)給從服務(wù)器。
如果期間連接斷了,當(dāng)從服務(wù)器重新連上主服務(wù)器后,上述的步驟會重新來一遍??梢园l(fā)現(xiàn)這是很低效的,因?yàn)橹鞣?wù)器只需要把斷連期間的寫入命令發(fā)給從服務(wù)器就可以了,不需要重新生成RDB文件。(生成RDB文件是一個(gè)耗時(shí)操作,設(shè)計(jì)磁盤的讀寫)。
注意:從服務(wù)器在加載RDB文件過程中是阻塞的,無法處理客戶端的請求。
2.3 主從復(fù)制的原理V2
基于上述原因(特別是斷線時(shí)間特別短時(shí)),Redis推出了新的同步命令psync。
psync將同步過程分為了兩塊:1、完整同步;2、部分同步。
完整同步也叫初次同步,也就是第一次主從同步。步驟跟v1上述是一致的。
部分同步主要用戶斷線重連后的同步,它可以將斷線期間的寫入命令發(fā)送給從服務(wù)器,而不需要整個(gè)RDB文件,極大的節(jié)約了資源。當(dāng)從服務(wù)器重新連接了主服務(wù)器后,會發(fā)送psync命令,然后主服務(wù)器回復(fù)continue命名,并且發(fā)送缺少的寫入命令到從服務(wù)器。
2.3.1 部分同步原理
redis完成部分同步功能主要依賴于以下部分:
1、主服務(wù)器的復(fù)制偏移量
2、從服務(wù)器的復(fù)制偏移量
3、命令緩存區(qū)(FIFO隊(duì)列,默認(rèn)大小1MB)
4、服務(wù)器運(yùn)行Id
每次主服務(wù)器向從服務(wù)器傳遞N個(gè)字節(jié)命令后,就在把自己的偏移量+N。從服務(wù)器同理。同時(shí)主服務(wù)器還會將命令寫入到命令緩存區(qū)里。當(dāng)從服務(wù)器重連是發(fā)生如下步驟:

每個(gè)Redis都有自己的唯一標(biāo)識Id。在啟動時(shí)自動生成,由40個(gè)隨機(jī)的十六進(jìn)制字符組成。當(dāng)發(fā)送第一次主從同步時(shí),master會將自己的id發(fā)送會從服務(wù)器,從服務(wù)器會將其保存起來。斷線重連時(shí),從服務(wù)器請求同步時(shí)還會將這個(gè)id發(fā)送給主服務(wù)器,主服務(wù)器判斷該id與自己的id是否一致,如果一致則繼續(xù)執(zhí)行部分同步的剩余步驟。否則執(zhí)行完整同步。
2.4 心跳檢測
主從服務(wù)器建立連接后,默認(rèn)每隔1秒,從服務(wù)器會想主服務(wù)器發(fā)送REPLCONF_ACK <offset>報(bào)告自己的狀態(tài)。
主服務(wù)器可以從這個(gè)命令中檢測出幾個(gè)問題:
1、主從之間的網(wǎng)絡(luò)連接狀態(tài)
? 如果主服務(wù)器在規(guī)則時(shí)間內(nèi)沒有收到從服務(wù)器的心跳命令,就可以認(rèn)為主從之間出現(xiàn)了問題。這個(gè)時(shí)候如果配置了
min-slaves-to-write 3
min-slaves-max-lag 10
//如果從服務(wù)器數(shù)小于3或者3個(gè)服務(wù)器的心跳檢測延遲值都大于等于10秒,主服務(wù)器將拒絕寫命令
2、檢測新的寫命令是否丟失
? 每次主服務(wù)器收到從服務(wù)器心跳命令里的offset時(shí),都會與自己的offset進(jìn)行比較,如果小于自己的。那么可以知道某次傳遞的寫命令在網(wǎng)絡(luò)上丟失或者從服務(wù)器加載失敗,這個(gè)時(shí)候主服務(wù)器會主動將這部分缺少的命令發(fā)送給從服務(wù)器(需要缺失命令還在緩存區(qū),如果不在猜測應(yīng)該是發(fā)起一次完整同步,未驗(yàn)證過)。
3、輔助實(shí)現(xiàn)min-slaves
2.5 備注
主從服務(wù)器建立套接字連接后,從服務(wù)器首先會發(fā)起Ping命令檢測套接字的讀寫是否正常。收到主服務(wù)器的Pong命令后證明正常。然后在判斷主服務(wù)器是否需要身份認(rèn)證,發(fā)起密碼。然后進(jìn)行復(fù)制流程。