Redis面試篇 — Redis主從複製原理

  • 2019 年 10 月 14 日
  • 筆記

    Redis一般是用來支撐讀高並發的,為了分擔讀壓力,Redis支援主從複製。架構是主從架構,一主多從, 主負責寫,並且將數據複製到其它的 slave 節點,從節點負責讀。 所有的讀請求全部走從節點。這樣也可以很輕鬆實現水平擴容,支撐讀高並發。
 
redis主從複製的特點:
  • redis採用非同步方式複製數據到slave節點,從redis2.8開始,slave節點會周期性地確認自己每次複製的數據量;
  • 一個master節點可以配置多個slave節點;
  • slave節點可以連接其他的slave節點;
  • slave節點做複製的時候,不會阻塞master節點的正常工作;
  • slave節點做複製的時候,也不會阻塞對自己的查詢操作,它會用舊數據集來提供服務,但在複製完成時,需要刪除舊數據集,載入新數據集,這時會暫停對外服務;
  • slave節點主要用來橫向擴容,做讀寫分離,擴容的slave節點可以提高讀的吞吐量;
  • 如果採用主從架構,必須開啟master節點的持久化,不建議用slave節點作master節點的數據熱備,因為如果一旦關掉master的持久化,可能在master宕機重啟時數據是空的,然後一經複製,slave節點也會隨之丟失。
 

主從複製


    Redis主從複製分為全量複製和增量複製。
    全量複製一般發生在Slave初始化階段,這時slave需要將master上的所有數據都複製一份。步驟如下:
  • 從伺服器連接主伺服器,發送psync命令;
  • 主伺服器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的所有寫命令;
  • 主伺服器BGSAVE執行完後,向所有從伺服器發送快照文件,並在發送期間繼續記錄被執行的寫命令; 
  • 從伺服器收到快照文件後丟棄所有舊數據,載入收到的快照; 
  • 主伺服器快照發送完畢後開始向從伺服器發送緩衝區中的寫命令;
  • 從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;
 
    增量複製一般是 Slave初始化後開始正常工作時主伺服器發生的寫操作同步到從伺服器的過程。步驟如下:
  • 如果全量複製過程中,master-slave 網路連接斷掉,那麼 slave 重新連接 master 時,會觸發增量複製。
  • master 直接從自己的 backlog 中獲取部分丟失的數據,發送給 slave node,默認 backlog 就是 1MB。
  • master 就是根據 slave 發送的 psync 中的 offset 來從 backlog 中獲取數據的。
 

其他知識點(可忽略)


Redis主從複製的核心原理

    slave節點初次連接master節點,會發送psync命令並觸發全量複製。此時master開啟一個後台執行緒,開始生成一份RDB快照,同時將那些從外面接收到的寫命令快取到緩衝區中。RDB文件生成完畢後,將此文件發送給slave節點,slave先寫入磁碟,再從磁碟載入到記憶體,接著master會將緩衝區中的寫命令發送給slave,slave執行寫命令並同步數據。如果slave節點和master節點因網路故障斷開連接,會自動重連,連接之後master節點會複製缺少的數據給slave節點。
 

主從複製的斷點續傳

    從redis2.8開始支援主從複製的斷點續傳,主從複製過程中網路連接斷開了,會接著從上次斷開的地方繼續複製,而不是從頭開始複製。
    master節點會在記憶體中維護一個backlog,master和slave都會保存一個replica offset和一個master run id,offset就在backlog中,master和slave斷開時,slave會讓master從上次replica offset開始繼續複製,如果沒找到對應的offset,就會執行一次  resynchronization。

 

無磁碟化複製

    master在記憶體中創建RDB,然後發送給RDB,不會在自己本地落地磁碟了,只需要在配置文件中開始repl-diskless-sync-delay即可。
 

過期key處理

    slave不會處理過期key,只能等待master處理。如果master處理了一個key,或者通過LRU淘汰了一個key,那麼會模擬一條del命令發送給slave。
 

heartbeat

    主從節點會相互發送heartbeat資訊。master默認每隔10秒發送一次heartbeat,slave節點每隔1秒發送一次heartbeat。
 

非同步複製

    master每次接收到寫命令之後,先在內部寫入數據,然後非同步發送給slave節點。
 

Redis如何做到高可用


    如果系統99%的時間都用於對外服務,那麼系統可以說是高可用的。
    一個slave節點掛掉,並不會影響系統的高可用性,其他slave節點可以提供相同的數據對外服務。
    但如果master節點掛掉了,就無法寫入數據了,導致slave節點得不到最新的數據,這時就相當於系統不可用了。Redis的高可用架構,叫做failover故障轉移,也就主備切換。master節點故障時會自動檢測,並將某個slave節點自動切換成master節點的過程,叫做主備切換。這個過程,實現了Redis主從架構的高可用。