redis緩存架構詳解(五)- redis 主從架構-redis replication原理分析

4. redis 主從架構redis replication:實現高併發高可用

單臺redis的侷限性:

  1. 內存上,單個Redis的內存不宜過大,內存過大會導致主從同步時全量同步時間過長,而且在實例重啓恢復時也會消耗很長的數據加載時間,一般控制在10G以內即可。
  2. CPU 的利用率上,單個 Redis 實例只能利用單個核心,這單個核心在面臨海量數據的存取和管理工作時壓力會非常大。
  3. 單機redis,能夠支撐QPS大概在5萬左右,如果上千萬的用戶訪問,redis就承載不了,成爲了高併發的瓶頸。
redis 主從架構redis replication:實現高併發高可用。

4.1. redis replication架構

4.1.1. redis是實現系統高併發的重要緩存技術

mysql能支持的高併發,是通過一系列複雜的分庫分表,訂單系統,事務控制等達到的,且QPS只到幾萬,不會再高。除非一些特殊情況,如服務器性能特別好,配置特別高,維護做的特別好,且整體的操作不是太複雜。

真正的超高併發,QPS上十萬,甚至是百萬。平臺提供高併發最重要的是緩存架構,而redis是實現緩存架構最重要的技術。使用redis技術搭建緩存架構(讀寫分離、多級緩存架構、熱點緩存),能支撐真正的上十萬,甚至上百萬的高併發。

讀寫分離一般都是用來支撐讀高併發,寫的請求比較少,可能寫請求也就一秒鐘幾千,而讀一秒鐘二十萬次左右。

4.1.2. redis replication架構

Redis replication 是一種 master-slave 模式的複製機制,這種機制使得 slave 節點可以成爲與 master 節點完全相同的副本。架構如下:

在這裏插入圖片描述

1、redis採用異步方式複製數據到slave節點,不過redis 2.8開始,slave node會週期性地確認自己每次複製的數據量。
2、一個master node是可以配置多個slave node。
3、slave node也可以連接其他的slave node。
4、slave node做複製的時候,是不會阻塞 master node的正常工作。
5、slave node在做複製的時候,也不會阻塞對自己的查詢操作,它會用舊的數據集來提供服務; 但是複製完成的時候,需要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了。
6、slave node主要用來進行橫向擴容,做讀寫分離,擴容的slave node可以提高讀的吞吐量。

我們知道,單個 Redis 節點也是可以直接工作的。那爲什麼一個 Redis 節點(master)還需要一個或多個副本(slave)呢?或者說 replication 到底想要解決什麼問題

4.1.2.1. redis replication實現讀擴展

一個 master 用於寫,多個 slave 用於分攤讀的壓力。

在這裏插入圖片描述

4.1.2.2. redis replication實現高可用

如果 master 掛掉了,可以提升(promote)一個 slave 爲新的 master,進而實現故障轉移(failover)。

在這裏插入圖片描述

4.2. master持久化、備份對主從架構的安全意義

1、master node必須做持久化

**使用主從架構,必須開啓master node的持久化!不建議用slave node作爲master node的數據熱備。**

master的持久化關閉,可能在master宕機重啓的時候數據是空的(RDB和AOF都關閉了),此時就會將空數據複製到salve ,導致slave node數據也丟了。

2、master node必須做好備份方案

使用主從架構,master要做好各種備份方案,如果本地的所有文件丟失了;,可以從備份中挑選一份rdb去恢復master, 這樣才能確保master啓動的時候,能從rdb、aof文件中加載數據,保證master有數據,從而也保證了各個slave node有數據。

即使採用了哨兵sentinel高可用機制,slave node可以自動接管master node,但是也可能sentinel還沒有檢測到master failure,master node就自動重啓了,還是可能導致上面的所有slave node數據清空故障

4.3. redis主從複製核心原理

4.3.1. 主從架構複製的核心原理

在這裏插入圖片描述

1、主要原理

1、當啓動一個slave node的時候,它會發送一個PSYNC命令給master node,此時slave node僅保存master node的信息,包括master node的host和ip,但是複製流程沒開始。master host和ip是配置在redis.conf裏面的slaveof。

(1)slave node內部有個定時任務,每秒檢查是否有新的master node要連接和複製,如果發現,就跟master node建立socket網絡連接
(2)slave node發送ping命令給master node
(3)口令認證,如果master設置了requirepass,那麼salve node必須發送masterauth的口令過去進行認證

2、如果slave node重新連接master node,那麼master node僅僅會複製給slave部分缺少的數據;

3、如果slave node第一次連接master node,那麼會觸發一次full resynchronization

(1)開始full resynchronization的時候,master會啓動一個後臺線程,開始生成一份RDB快照文件。

(2)此時如果客戶端有寫入數據到master,所有寫命令緩存在內存中。

(3)RDB文件生成完畢之後,master會將這個RDB發送給slave,slave會先寫入本地磁盤,然後再從本地磁盤加載到內存中。

(4)然後master會將內存中緩存的寫命令發送給slave,slave也會同步這些數據。

4、slave node如果跟master node有網絡故障,斷開了連接,會自動重連。

5、master如果發現有多個slave node都來重新連接,僅僅會啓動一個rdb save操作,用一份數據服務所有slave node。

(5)master node第一次執行全量複製,將所有數據發給slave node
(6)master node後續持續將寫命令,異步複製給slave node

2、數據同步相關的核心機制

指的就是第一次slave連接msater的時候,執行的全量複製,那個過程裏面你的一些細節的機制

(1)master和slave都會維護一個offset

master會在自身不斷累加offset,slave也會在自身不斷累加offset
slave每秒都會上報自己的offset給master,同時master也會保存每個slave的offset

這個倒不是說特定就用在全量複製的,主要是master和slave都要知道各自的數據的offset,才能知道互相之間的數據不一致的情況

(2)backlog

master node有一個backlog,默認是1MB大小。
master node給slave node複製數據時,也會將數據在backlog中同步寫一份。
backlog主要是用來做全量複製中斷網後的增量複製。

(3)master run id

info server,可以看到master run id
如果根據host+ip定位master node,是不靠譜的,如果master node重啓或者數據出現了變化,那麼slave node應該根據不同的run id區分,run id不同就做全量複製
如果需要不更改run id重啓redis,可以使用redis-cli debug reload命令

(4)psync

從slave節點使用psync到master node進行復制,psync runid offset
master node會根據自身的情況返回響應信息,可能是FULLRESYNC runid offset觸發全量複製,可能是CONTINUE觸發增量複製。

3、全量複製

(1)master執行bgsave,在本地生成一份rdb快照文件
(2)master node將rdb快照文件發送給salve node,如果rdb複製時間超過60秒(repl-timeout),那麼slave node就會認爲複製失敗,可以適當調節大這個參數
(3)對於千兆網卡的機器,一般每秒傳輸100MB,6G文件,很可能超過60s
(4)master node在生成rdb時,會將所有新的寫命令緩存在內存中,在salve node保存了rdb之後,再將新的寫命令複製給salve node
(5)client-output-buffer-limit slave 256MB 64MB 60,如果在複製期間,內存緩衝區持續消耗超過64MB,或者一次性超過256MB,那麼停止複製,複製失敗
(6)slave node接收到rdb之後,清空自己的舊數據,然後重新加載rdb到自己的內存中,同時基於舊的數據版本對外提供服務
(7)如果slave node開啓了AOF,那麼會立即執行BGREWRITEAOF,重寫AOF

rdb生成後、通過網絡拷貝到slave,slave舊數據的清理、slave aof rewrite,很耗費時間

如果複製的數據量在4G~6G之間,那麼很可能全量複製時間消耗到1分半到2分鐘

4、增量複製

(1)如果全量複製過程中,master-slave網絡連接斷掉,那麼salve重新連接master時,會觸發增量複製。
(2)master直接從自己的backlog中獲取部分丟失的數據,發送給slave node,默認backlog就是1MB。
(3)msater就是根據slave發送的psync中的offset來從backlog中獲取數據的。

5、heartbeat

  	主從節點互相都會發送heartbeat信息。master默認每隔10秒發送一次heartbeat,salve node每隔1秒發送一個heartbeat

6、異步複製

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

4.3.2. 主從複製的斷點續傳

從redis 2.8開始,redis 就支持主從複製的斷點續傳,如果主從複製過程中,網絡連接斷掉了,那麼可以接着上次複製的地方,繼續複製下去,而不是從頭開始複製一份。

原理:

  	master node會在內存中保存一個backlog,master和slave都會保存一個replica offset,還有一個master id,offset就是保存在backlog中的。如果master和slave網絡連接斷掉了,slave會讓master從上次的replica offset開始繼續複製。
  	
  	但是如果沒有找到對應的offset,那麼就會執行一次resynchronization

4.3.3. 無磁盤化複製

master在內存中直接創建rdb,然後發送給slave,不會在本地磁盤創建。

在redis.conf中有兩個配置:

在這裏插入圖片描述

repl-diskless-sync :是否開啓無磁盤複製
repl-diskless-sync-delay:等待一定時長再開始複製,因爲要等更多slave重新連接過來

4.3.4. 過期key處理

slave不會出現過期的key,只會等待master過期的key。如果master過期了一個key,或者通過LRU淘汰了一個key,那麼會模擬一條del命令發送給slave。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章