日常工作中使用的Redis集羣是一主多從的架構模型(如下圖),當主1發生宕機時,會切寫到從(爲了方便製作預案主1主2同時1切寫到從1),此時面臨的問題是主2沒有宕機,如果直接寫從2,那寫進從2的數據會不會被主2重新覆蓋(主2沒有宕機)?
針對以上問題引申出Redis主從同步的機制問題,學習瞭解後記錄如下:
Redis主從同步分爲兩種機制:全量同步、增量同步。
主從複製過程:
當設置好slave服務器後,slave會建立和master的連接,然後發送sync命令。無論是第一次同步建立的連接還是連接斷開後的重新連接,master都會啓動一個後臺進程,將數據庫快照保存到文件中,同時master主進程會開始收集新的寫命令並緩存起來。後臺進程完成寫文件後,master就發送文件給slave,slave將文件保存到磁盤上,然後加載到內存恢復數據庫快照到slave上。接着master就會把緩存的命令轉發給slave。而且後續master收到的寫命令都會通過開始建立的連接發送給slave。從master到slave的同步數據的命令和從 client發送的命令使用相同的協議格式。當master和slave的連接斷開時slave可以自動重新建立連接。如果master同時收到多個 slave發來的同步連接命令,只會使用啓動一個進程來寫數據庫鏡像,然後發送給所有slave。
總結如下:
當Slave需要和Master進行數據同步時:
1) Salve會發送sync命令到Master
2) Master啓動一個後臺進程,將Redis中的數據快照保存到文件中
3) 啓動後臺進程的同時,Master會將保存數據快照期間接收到的寫命令緩存起來
4) Master完成寫文件操作後,將該文件發送給Salve
5) Salve將文件保存到磁盤上,然後加載文件到內存恢復數據快照到Salve的Redis上
6) 當Salve完成數據快照的恢復後,Master將這期間收集的寫命令發送給Salve端
7) 後續Master收集到的寫命令都會通過之前建立的連接,增量發送給salve端
總結一下,主從剛剛連接的時候,進行全量同步;全同步結束後,進行增量同步。當然,如果有需要,slave 在任何時候都可以發起全量同步。所以,回到我們最初的疑問,正常情況下,當切寫到從2時,主2由於沒有數據寫入不會觸發增量同步也不會觸發全量同步,所以正常情況下主2的數據不會覆蓋從2新寫入的數據。
其他
Redis 2.8以後提供了PSYNC優化了斷線重連的效率 ,具體參考另外一篇博客
http://blog.csdn.net/sk199048/article/details/77922589