目前redis僅支持主從複製模式,能夠支持在線備份、讀寫分離等功能,實際應用中一般經過sentinel服務作主從切換的管理,這增長了管理的複雜度和維護成本,基於此360基礎架構組聯合DBA從redis內部實現了雙主功能。 redis
redis支持樹形的主從異步複製,並具備非阻塞、部分同步等特性,下面簡單介紹下其實現原理以及目前redis主從複製模式在故障發生時的數據丟失狀況。 緩存
slave開始鏈接到master時須要同步master已有的數據,具體過程以下圖所示,主要有如下幾個步驟: 網絡
master 實例會維護其slave實例列表,當有更改操做發生時,其會經過鏈接創建時建立的socket向全部slave實例發送操做命令進行數據傳播,同時爲了防 止故障恢復slave從新鏈接master時每次都進行全量同步,master實例會內部維護一個緩衝區(積壓空間)來緩存部分slave命 令,master數據傳播的具體過程爲: 架構
redis 主從模式並不能保證數據的100%完整,在網絡故障、主庫宕機等狀況下提高slave爲master時可能會丟失部分數據,以下圖所示,假如在某個時刻 master的數據還未徹底傳播給slave時,master宕機等狀況發生並將slave提高爲master,這時原來master未傳播的一部分數據 將丟失。 異步
因爲時間、精力等因素,目前咱們在進行雙主設計時結合以下實際項目需求進行了一些設計折衷,後續咱們會繼續完善相關設計。 socket
上層保證某個時間點只有一個master在寫 性能
故障時容許丟失少許數據 spa
爲 避免額外維護成本,雙主模塊徹底在redis內部實現,雙主兩個實例各自建立一個socket進行彼此通訊;加入雙主複製後不會影響原有的主從複製模式, 但以下圖所示,主從複製實例能夠經過咱們新增的doublemasterof命令轉化爲雙主複製,雙主複製實例也能夠經過原有的slaveof命令轉換爲 主從複製實例。 設計
redis 雙主實例網絡故障恢復或重啓等狀況下會進行從新鏈接以同步彼此數據,主從模式下同步策略很簡單,只須要從庫同步主庫數據便可,而雙主模式下咱們必須根據一 定的策略來選出一個實例做爲數據同步的對象,咱們考慮到兩種具體同步策略:基於數據量和基於時間戳的同步策略。 對象
基 於數據量的同步策略能夠理解爲數據量少的實例去同步數據量多的實例,這種同步策略在故障發生時數據已經所有傳播到另一個實例的狀況下,故障恢復後能夠保 證數據完整性,但以下圖所示,假如原來操做在雙主A上執行,某一時刻雙主A上的操做還未同步到雙主B上發生了網絡故障,上層會切到B上繼續寫入,當寫入了 圖中紅色所示大小的數據後網絡故障恢復,這時進行數據同步時就有可能丟失A或B上的部分數據。
對 於基於時間戳的同步策略,咱們會在redis內部維護雙主實例的最近更新時間戳,故障恢復進行數據同步時時間戳較舊的實例會同步時間戳較新的實例;和基於 數據量同步策略同樣當故障發生時若是數據已經所有傳播到另外實例則故障恢復後能夠保證數據完整性,不然,以下圖所示故障恢復後將丟失雙主A實例的部分數 據。
根據業務需求,咱們須要保證最新寫入的數據不會丟失,因此具體實現上咱們選擇了基於時間戳的同步策略。
咱們在redis原有的全同步,部分同步的基礎上增長了ignore resync策略以實現雙主同步,具體實現以下圖所示,有如下幾個步驟:
對 一個雙主實例的更改操做,redis內部會經過雙主實例創建鏈接時建立的socket異步傳播給另外一個雙主實例,這裏要解決的問題是要避免數據再次傳播回 來,具體實現上咱們經過雙主實例的runid進行判斷,每一個雙主實例內部會維護其另一個實例的runid信息,當有更改命令要執行時,咱們會經過 runid來判斷該命令是不是其雙主實例傳播過來的,若是是將再也不回傳。
redis主從實現機制上,當通訊模塊接收到主庫的更改命令時會直接在從庫上增長其複製偏移量來記錄數據同步的位置,而對於雙主實例咱們知道爲避免數據循環傳播,雙主實例A傳播給雙主實例B的命令不會回傳過來,那麼該如何維護其複製偏移量呢?設計上咱們考慮了兩種策略:
以下圖所示,雙主A向雙主B傳播一條數據後,B會回覆A一個ACK length確認,A接收到確認信息後將本身的複製偏移量增長length。
以下圖所示,雙主A再向B傳播數據以前本身主動增長複製偏移量,雙主B不會向雙主A回覆確認信息
策略一對比策略二進一步保證了數據的完整性,但同時帶來了必定的網絡開銷,兩種策略都不能徹底保證複製偏移量再網路故障下的正確性(策略一在ACK丟失的狀況下沒法保證複製偏移量正確),結合目前的需求爲了避免影響性能咱們選擇了策略二。
結合目前項目的需求咱們在redis內部實現了雙主功能,可是也有一些須要改進的地方,歡迎你們提出意見,後面咱們會不斷完善,敬請關注!
http://weibo.com/p/1001603872517453663800