1、redis主從復制過程
先不解釋replication buffer和replication backlog,而先看看redis主從復制的過程。
redis的主從復制分為兩個階段:
1)同步(sync rdb snapshot):slave復制master的某時間點(t)的全量數據,t為master接收到slave的sync命令后執行rdb bgsave的時間點。2.8增加psync,支持full resync和partial resync命令。master發送rdb文件到slave,slave讀取rdb把數據加載到內存。
2)命令傳播(commands propagation):同步時間點t后master上的數據更新到slave上, 發送的數據是redis的命令。
2、replication buffer的作用
redis的slave buffer(replication buffer,master端上)存放的數據是下面三個時間內所有的master數據更新操作。
1)master執行rdb bgsave產生snapshot的時間
2)master發送rdb到slave網絡傳輸時間
3)slave load rdb文件把數據恢復到內存的時間
replication buffer太小會引發的問題:
replication buffer由client-output-buffer-limit slave設置,當這個值太小會導致主從復制鏈接斷開。
1)當master-slave復制連接斷開,server端會釋放連接相關的數據結構。replication buffer中的數據也就丟失了,此時主從之間重新開始復制過程。
2)還有個更嚴重的問題,主從復制連接斷開,導致主從上出現rdb bgsave和rdb重傳操作無限循環。
查看[top redis headaches for devops – replication buffer]
因而推薦把slave replication buffer的hard/soft limit設置成512M
config set client-output-buffer-limit "slave 536870912 536870912 0"
3、replication backlog的出現
在2.8版本,redis使用了新的復制方式,引入了復制積壓緩沖(replication backlog)。
查看[Designing Redis replication partial resync]
上圖來自《redis設計與實現》
當主服務器進行命令傳播的時候,maser不僅將所有的數據更新命令發送到所有slave的replication buffer,還會寫入replication backlog。當斷開的slave重新連接上master的時候,slave將會發送psync命令(包含復制的偏移量offset),請求partial resync。如果請求的offset不存在,那么執行全量的sync操作,相當于重新建立主從復制。
4、區分replication buffer 和 replication backlog
1) replication buffer對應于每個slave,通過config set client-output-buffer-limit slave 設置。
2) replication backlog是一個環形緩沖區,整個master進程中只會存在一個,所有的slave公用。backlog的大小通過repl-backlog-size參數設置,默認大小是1M,其大小可以根據每秒產生的命令、(master執行rdb bgsave) +( master發送rdb到slave) + (slave load rdb文件)時間之和來估算積壓緩沖區的大小,repl-backlog-size值不小于這兩者的乘積。
參考資料:
[1] redis設計與實現(黃健宏)
[2] redis replication(http://redis.io/topics/replication)
[3] [Designing Redis replication partial resync](http://antirez.com/news/31)
原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/2478