Redis【一】Redis主從復(fù)制原理
Redis【二】Redis哨兵模式原理

如上圖所示展示了Redis主從復(fù)制的主要過程
- 在slave節(jié)點上配置replicaof(老版本是slaveof) {主節(jié)點IP:Port}
- slave節(jié)點發(fā)現(xiàn)master節(jié)點配置有變更,就嘗試與master節(jié)點建立socket連接
- slave發(fā)送ping,如果沒有及時收到master的pong,slave會1s重試一次
- slave發(fā)送權(quán)限驗證
- slave節(jié)點向master節(jié)點發(fā)送sync/psync命令,如果是psync命令,master節(jié)點會根據(jù)psync的offset參數(shù)決定是部分還是全量同步(首次連接時一般都會是全量同步,斷線重連的話可能會是部分同步),master節(jié)點執(zhí)行bgsave,把全量rdb數(shù)據(jù)通過socket的方式傳給slave節(jié)點
- master在執(zhí)行basave的時候會把之后的接收處理的所有寫命令寫入到副本客戶端緩沖區(qū)(緩沖區(qū)的大小由client-output-buffer-limit slave 配置),如果緩沖區(qū)超過了配置的緩沖區(qū)大小限制,master就會停止當(dāng)前同步過程,當(dāng)前同步就會失敗。
Redis數(shù)據(jù)同步
Redis2.8之后支持psync,psync在同步階段可以根據(jù)場景決定使用全量同步或部分同步。
使用部分同步的條件:
- 主從節(jié)點各自復(fù)制偏移量
- 主節(jié)點復(fù)制積壓緩沖區(qū)
- 主節(jié)點運行 ID
主從節(jié)點各自復(fù)制偏移量:
參與復(fù)制的主從節(jié)點都會維護自身的復(fù)制偏移量。
主節(jié)點在處理完寫入命令后,會把命令的字節(jié)長度做累加記錄,統(tǒng)計信息在 info replication 中的 masterreploffset 指標(biāo)中。
從節(jié)點每秒鐘上報自身的的復(fù)制偏移量給主節(jié)點,因此主節(jié)點也會保存從節(jié)點的復(fù)制偏移量。
從節(jié)點在接收到主節(jié)點發(fā)送的命令后,也會累加自身的偏移量,統(tǒng)計信息在 info replication 中。
通過對比主從節(jié)點的復(fù)制偏移量,可以判斷主從節(jié)點數(shù)據(jù)是否一致。
主節(jié)點復(fù)制積壓緩沖區(qū):
復(fù)制積壓緩沖區(qū)是一個保存在主節(jié)點的一個固定長度的先進先出的隊列,默認大小 1MB。該配置由參數(shù)repl_backlog_size設(shè)置
這個隊列在 slave 連接是創(chuàng)建。這時主節(jié)點響應(yīng)寫命令時,不但會把命令發(fā)送給從節(jié)點,也會寫入復(fù)制緩沖區(qū)。
他的作用就是用于部分復(fù)制和復(fù)制命令丟失的數(shù)據(jù)補救。
主節(jié)點運行 ID:
每個 redis 啟動的時候,都會生成一個 40 位的運行 ID。
運行 ID 的主要作用是用來識別 Redis 節(jié)點。如果使用 ip+port 的方式,那么如果主節(jié)點重啟修改了 RDB/AOF 數(shù)據(jù),從節(jié)點再基于偏移量進行復(fù)制將是不安全的。所以,當(dāng)運行 id 變化后,從節(jié)點將進行全量復(fù)制。也就是說,redis 重啟后,默認從節(jié)點會進行全量復(fù)制。
psync命令的格式是psync {masterrunid} {offset}
master如果判斷slave發(fā)送的offset還在復(fù)制積壓緩沖區(qū)中,就會返回+CONTINUE進行部分復(fù)制,否則會返回+FULLRESYNC {runId} {offset} 進行全量復(fù)制。
全量復(fù)制

- slave向master發(fā)送psync命令
- master發(fā)現(xiàn)offset已經(jīng)不在復(fù)制積壓緩沖區(qū),就返回FullReSync {runId} {offset} 準(zhǔn)備執(zhí)行全量同步
- slave保存master的runI offset信息
- master執(zhí)行basave保存的rdb數(shù)據(jù),slave把接收到的rdb文件寫入磁盤上。
redis支持無盤復(fù)制(repl-diskless-sync設(shè)置為true),另外可以通過repl-diskless-sync-delay 5設(shè)置延遲5秒執(zhí)行bgsave,這樣可以等待更多的slave sync請求,就可以多個slave使用同一個rdb文件,否則的話其他的slave需要等當(dāng)前bgsave結(jié)束之后才能執(zhí)行同步操作。
master執(zhí)行bgsave之后會把之后的所有寫命令放入復(fù)制網(wǎng)絡(luò)緩沖區(qū),該大小由參數(shù)client-output-buffer-limit slave設(shè)置。 - master向slave發(fā)送rdb數(shù)據(jù)
- master把剛才復(fù)制網(wǎng)絡(luò)緩沖區(qū)中的寫命令發(fā)送給slave
- slave清空當(dāng)前實例中的數(shù)據(jù)
- slave加載master發(fā)來的rdb文件
部分復(fù)制

- slave與master斷開連接
- master持續(xù)把接收到的寫命令寫入復(fù)制擠壓緩沖區(qū)(repl-backlog-buffer)
- slave與master重新連接
- slave發(fā)送psync {offset} {runid} runid是slave中記錄的master的runid
- master收到psync命令,比對runid與當(dāng)前運行實例的runid相同,offset還在repl-bakclog-offset中,可以部分復(fù)制,就返回lsave CONTINUE
- 根據(jù)slave的offset發(fā)送slave缺失的命令