天天看點

14.Redis叢集主從複制原理

       Redis是一個開源的key value存儲系統,受到了廣大網際網路公司的青睐。Redis3.0版本之前隻支援單節點運作模式,在3.0版本及以後才支援叢集。

       雖然Redis有持久化功能,能夠保障redis伺服器當機也能恢複并且隻有少量資料丢失(不建議使用redis來做持久化的處理),但是由于所有資料在一台伺服器上,如果這台伺服器出現硬碟故障,那就算是有備份也仍然不可避免資料丢失的問題。

       在實際生産環境中,我們不可能使用一台redis伺服器來作為我們的緩存伺服器,是以為了避免單點故障問題,必須要使用多台伺服器來實作Redis叢集。[如需了解Redis叢集安裝,請移步:Redis-5.0.3叢集安裝]

主從複制(資料同步)

       主從複制,可以實作當一台Redis伺服器的資料更新後,自動将新的資料同步到叢集中的其他伺服器上,進而保證資料一緻,主要用來解決Redis叢集多節點之間資料的同步問題。

       Redis叢集的出現,能夠解決①單點故障的問題的同時,也能夠實作②讀寫分離的操作(master負責寫,slave負責讀)

原理

       Redis的主從複制可以確定Redis叢集的master和slave之間的資料同步。主從複制可以分為①全量複制和②增量複制,在Redis2.8版本之後,引入了③無磁盤複制。本文将對這三種複制進行簡單的了解。

 1.全量複制

        Redis的全量複制,一般發生在slave節點初始化階段。這時候slave節點需要将master節點上的所有資料都複制一份,詳細步驟如下圖所示。(基于RDB快照方式)

14.Redis叢集主從複制原理

        完成上圖步驟,即完成了slave節點資料初始化的所有操作,slave節點此時便可以接受來自使用者的讀請求操作。Redis叢集中的master/slave的複制政策采用的是樂觀複制,也就是說可以容忍在一定時間内master/slave資料的内容是不同的,但是兩者的資料都會最終同步一緻的。

       為什麼在一段時間内master/slave資料的内容是不同的呢?因為Redis的主從複制同步過程是異步操作的,即:master執行完用戶端請求指令後,會立即将結果傳回給用戶端,然後再異步将指令同步給slave,進而導緻master/slave節點在短時間内的資料不一緻性。切記:Redis遵循的是弱一緻性原則。

       為什麼要采用異步操作呢?因為Redis是基于記憶體的一個非關系型資料庫,性能是非常快的,如果使用同步操作,可能會對Redis的性能有所影響,是以此處使用異步操作,可以保證Redis叢集的性能不受影響。

       你可能有疑惑,如果在資料不一緻期間,master/slave節點因為網絡問題等導緻連接配接斷開,而這個時候,master是無法得知某個寫指令是否最終同步給了多少個slave節點。此時Redis提供了一個配置項來限制master是否可寫,即:隻有master資料至少同步給多少個slave節點時,master節點才是可寫的。我們可以在redis.conf配置檔案中檢視。zhi

//表示隻有當3個或以上的slave連接配接到master,master才是可寫的
min-slaves-to-write 3   

//表示允許slave最長失去連接配接的時間,如果10秒還沒有收到slave的響應,則master認為該slave已斷開
min-slaves-max-lag 10  
           

2.增量複制

       Redis2.8版本開始,支援主從複制的斷點續傳,如果主從複制過程中,網絡連接配接斷開了,那麼可以接着上次複制的地方,繼續複制下去,而不是從頭開始複制。詳細步驟如下圖所示。

14.Redis叢集主從複制原理

       master節點會在記憶體中建立一個backlog,master和slave會儲存一個replica offset,還有一個master replid,offset就是儲存在backlog中。如果master和slave網絡連接配接斷開了,slave會讓master從上次的replica offset處開始複制。如果沒有找到對應的offset,那麼變會執行全量複制操作。(如下圖所示,為一主已從,我們能夠發現offset,backlog,master_replid等都是相同的,說明已經同步完成)

14.Redis叢集主從複制原理
14.Redis叢集主從複制原理

3.無磁盤複制

       Redis的全量複制,是基于RDB方式的持久化實作的,也就是master節點在背景儲存RDB快照,slave節點接收到rdb檔案,然後載入,完成複制操作。但是這種方式也會存在如下一些問題:

       ①當master節點禁用RDB方式,如果執行複制初始化操作,Redis依然會生成RDB快照,當master節點下次啟動時,執行該rdb檔案的恢複,因為複制發生的時間點不确定,導緻恢複的資料的時間點也不确定,可能是任何時間點的,進而導緻資料出現問題;

       ②當磁盤性能差,複制是存在性能過慢等問題,那麼初始化複制過程,便會對性能産生比較大的影響。

       基于以上問題,Redis在2.8.18以後的版本,引入了無硬碟複制這一選項,可以在不需要磁盤中的rdb檔案去同步,直接在記憶體中建立一個rdb檔案,直接發送資料至slave節點。在redis.conf配置檔案中,通過以下配置來開啟該功能:

//開啟無硬碟複制,預設為no 不開啟
repl-diskless-sync yes
           

至此,Redis叢集主從複制,資料一緻性原理講解完畢

END 

繼續閱讀