Redis主從架構機制是什么,考考你對Redis理解深度
Redis主從架構
單機的redis,能夠承載的QPS大概就在上萬到幾萬不等。對于緩存來說,一般都是用來支撐讀高并發的。因此架構做成主從(master-slave)架構,一主多從,主負責寫,并且將數據復制到其它的奴隸節點,從節點負責讀。所有的讀請求全部走從節點。這樣也可以很輕松實現水平擴容,支撐讀高并發。

redis replication - >主從架構 - >讀寫分離 - >水平擴容支撐讀高并發
redis replication的核心機制
- redis采用異步方式復制數據到slave節點,不過redis2.8開始,slave node會周期性地確認自己每次復制的數據量;
- 一個主節點是可以配置多個slave node的;
- slave node也可以連接其他的slave節點;
- slave node做復制的時候,不會阻塞主節點的正常工作;
- 奴隸節點在做復制的時候,也不會阻止對自己的查詢操作,它會用舊的數據集來提供服務;但是復制完成的時候,需要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了;
- slave node主要用來進行橫向擴容,做讀寫分離,擴展的slave node可以提高讀的吞吐量。
注意,如果采用了主從架構,那么建議必須開啟主節點的持久化,不建議用從節點作為主節點的數據熱備,因為那樣的話,如果你關掉master的持久化,可能在主宕機重啟的時候數據是空的,然后可能一經過復制,slave node的數據也丟了。
另外,master的各種備份方案,也需要做。萬一本地的所有文件丟失了,從備份中挑選一份rdb去恢復master,這樣才能確保啟動的時候,是有數據的,即使采用了后續講解的高可用機制,slave node可以自動接管master node,但也可能sentinel還沒檢測到master failure,master node就自動重啟了,還是可能導致上面所有的slave node數據被清空。
redis主從復制的核心原理
當啟動一個slave node的時候,它會發送一個PSYNC命令給主節點。
如果這是奴隸節點初次連接到主節點,那么會觸發一次full resynchronization全量復制。此時主會啟動一個后臺線程,開始生成RDB一份快照文件,同時還會將從客戶端客戶端新收到的所有寫命令緩存在內存中。RDB文件生成完畢后,master會將這個RDB發送給slave,slave會先寫入本地磁盤,然后再從本地磁盤加載到內存中,接著master會將內存中緩存的寫命令發送到slave,slave也會同步這些數據.slave node如果跟主節點有網絡故障,斷開了連接,會自動重連,連接之后主節點僅會復制給奴隸部分缺少的數據。

主從復制的斷點續傳
從redis2.8開始,就支持主從復制的斷點續傳,如果主從復制過程中,網絡連接斷掉了,那么可以接著上次復制的地方,繼續復制下去,而不是從頭開始復制一份。
主節點會在內存中維護一個backlog,master和slave都會保存一個副本偏移還有一個主運行id,offset就是保存在backlog中的。如果master和slave網絡連接斷掉了,slave會讓master從上次replica offset開始繼續復制,如果沒有找到對應的offset,那么就會執行一次resynchronization。
如果根據host + ip定位主節點,是不靠譜的,如果主節點重啟或者數據出現了變化,那么slave node應該根據不同的運行id區分。
無磁盤化復制
master在內存中直接創建RDB,然后發送給slave,不會在自己本地落地磁盤了。只需要在配置文件中開啟repl-diskless-sync yes即可。
repl-diskless-sync yes#等待5s后再開始復制,因為要等更多slave重新連接過來 repl-diskless-sync-delay 5
過期關鍵處理
slave不會過期密鑰,只會等待master過期密鑰。如果master過期了一個密鑰,或者通過LRU淘汰了一個密鑰,那么會模擬一條del命令發送給slave。
復制的完整流程
slave node啟動時,會在自己本地保存master node的信息,包括主節點的host和ip,但是復制流程沒開始。
slave node內部有個定時任務,每秒檢查是否有新的主節點要連接和復制,如果發現,就跟主節點建立socket網絡連接。然后slave節點發送ping命令給主節點。如果master設置了requirepass,那么slave node必須發送masterauth的口令過去進行認證.master node ***次執行全量復制,將所有數據發給slave node。而在后續,master node持續將寫命令,異步復制給slave node。

全量復制
master執行bgsave,在本地生成一份rdb快照文件。
主節點將rdb快照文件發送給從節點,如果rdb復制時間超過60秒(repl-timeout),那么slave節點就會認為復制失敗,可以適當調大這個參數(對于千兆網卡的機器,一般每秒傳輸100MB,6G文件,很可能超過60s)
主節點在生成rdb時,會將所有新的寫命令緩存在內存中,在從節點保存了rdb之后,再將新的寫命令復制給從節點。
如果在復制期間,內存緩沖區持續消耗超過64MB,或者一次性超過256MB,那么停止復制,復制失敗。
client-output-buffer-limit slave 256MB 64MB 60
slave node接收到rdb之后,清空自己的舊數據,然后重新加載rdb到自己的內存中,同時基于舊的數據版本對外提供服務。
如果slave node開啟了AOF,那么會立即執行BGREWRITEAOF,重寫AOF。
增量復制
如果全量復制過程中,master-slave網絡連接斷掉,那么奴隸重新連接master時,會觸發增量復制。
master直接從自己的backlog中獲取部分丟失的數據,發送給slave node,默認backlog就是1MB。
msater就是根據slave發送的psync中的offset來自backlog中獲取數據的。
心跳
主從節點互相都會發送心跳信息。
master默認每隔10秒發送一次heartbeat,slave node每隔1秒發送一個heartbeat。
異步復制
master每次接收到寫命令之后,先在內部寫入數據,然后異步發送給從屬節點。
redis如何才能做到高可用
如果系統在365天內,有99.99%的時間,都是可以嘩嘩對外提供服務的,那么就說系統是高可用的。
一個奴隸掛掉了,是不會影響可用性的,還有其它的奴隸在提供相同數據下的相同的對外的查詢服務。
但是,如果主節點死掉了,會怎么樣?沒法寫數據了,寫緩存的時候,全部失效了.slave node還有什么用呢,沒有master給它們復制數據了,系統相當于不可用了。
redis的高可用架構,叫做failover 故障轉移,也可以叫做主備切換。
主節點在故障時,自動檢測,并且將某個從節點自動切換位主節點的過程,叫做主備切換。這個過程,實現了redis的主從架構下的高可用。
后面會詳細說明redis 基于哨兵的高可用性。