Redis 主從架構

單機的 redis,可以承載的 QPS 大概就在上萬到幾萬不等。對於緩存來講,通常都是用來支撐讀高併發的。所以架構作成主從(master-slave)架構,一主多從,主負責寫,而且將數據複製到其它的 slave 節點,從節點負責讀。全部的讀請求所有走從節點。這樣也能夠很輕鬆實現水平擴容,支撐讀高併發node

Redis Replication -> 主從架構 -> 讀寫分離 -> 水平擴容支撐讀高併發redis

Redis Replication 的核心機制

  • redis 採用異步方式複製數據到 slave 節點,不過 redis2.8 開始,slave node 會週期性地確認本身每次複製的數據量;
  • 一個 master node 是能夠配置多個 slave node 的;
  • slave node 也能夠鏈接其餘的 slave node;
  • slave node 作複製的時候,不會 block master node 的正常工做;
  • slave node 在作複製的時候,也不會 block 對本身的查詢操做,它會用舊的數據集來提供服務;可是複製完成的時候,須要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了;
  • slave node 主要用來進行橫向擴容,作讀寫分離,擴容的 slave node 能夠提升讀的吞吐量。

注意,若是採用了主從架構,那麼建議必須開啓 master node 的持久化,不建議用 slave node 做爲 master node 的數據熱備,由於那樣的話,若是你關掉 master 的持久化,可能在 master 宕機重啓的時候數據是空的,而後可能一通過複製, slave node 的數據也丟了。sql

另外,master 的各類備份方案,也須要作。萬一本地的全部文件丟失了,從備份中挑選一份 rdb 去恢復 master,這樣才能確保啓動的時候,是有數據的,即便採用了後續講解的高可用機制,slave node 能夠自動接管 master node,但也可能 sentinel 還沒檢測到 master failure,master node 就自動重啓了,仍是可能致使上面全部的 slave node 數據被清空。shell

Redis 主從複製的核心原理

當啓動一個 slave node 的時候,它會發送一個 PSYNC 命令給 master node。segmentfault

若是這是 slave node 初次鏈接到 master node,那麼會觸發一次 full resynchronization 全量複製。此時 master 會啓動一個後臺線程,開始生成一份 RDB 快照文件,同時還會將從客戶端 client 新收到的全部寫命令緩存在內存中。RDB 文件生成完畢後, master 會將這個 RDB 發送給 slave,slave 會先寫入本地磁盤,而後再從本地磁盤加載到內存中,接着 master 會將內存中緩存的寫命令發送到 slave,slave 也會同步這些數據。slave node 若是跟 master node 有網絡故障,斷開了鏈接,會自動重連,鏈接以後 master node 僅會複製給 slave 部分缺乏的數據。緩存

主從複製的斷點續傳

從 redis2.8 開始,就支持主從複製的斷點續傳,若是主從複製過程當中,網絡鏈接斷掉了,那麼能夠接着上次複製的地方,繼續複製下去,而不是從頭開始複製一份。網絡

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

若是根據 host+ip 定位 master node,是不靠譜的,若是 master node 重啓或者數據出現了變化,那麼 slave node 應該根據不一樣的 run id 區分。

無磁盤化複製

master 在內存中直接建立 RDB,而後發送給 slave,不會在本身本地落地磁盤了。只須要在配置文件中開啓 repl-diskless-sync yes 便可。併發

repl-diskless-sync yes

# 等待 5s 後再開始複製,由於要等更多 slave 從新鏈接過來
repl-diskless-sync-delay 5

過時 key 處理

slave 不會過時 key,只會等待 master 過時 key。若是 master 過時了一個 key,或者經過 LRU 淘汰了一個 key,那麼會模擬一條 del 命令發送給 slave。less

複製的完整流程

slave node 啓動時,會在本身本地保存 master node 的信息,包括 master node 的hostip,可是複製流程沒開始。

slave node 內部有個定時任務,每秒檢查是否有新的 master node 要鏈接和複製,若是發現,就跟 master node 創建 socket 網絡鏈接。而後 slave node 發送 ping 命令給 master node。若是 master 設置了 requirepass,那麼 slave node 必須發送 masterauth 的口令過去進行認證。master node 第一次執行全量複製,將全部數據發給 slave node。而在後續,master node 持續將寫命令,異步複製給 slave node。

全量複製

  • master 執行 bgsave ,在本地生成一份 rdb 快照文件。
  • master node 將 rdb 快照文件發送給 slave node,若是 rdb 複製時間超過 60秒(repl-timeout),那麼 slave node 就會認爲複製失敗,能夠適當調大這個參數(對於千兆網卡的機器,通常每秒傳輸 100MB,6G 文件,極可能超過 60s)
  • master node 在生成 rdb 時,會將全部新的寫命令緩存在內存中,在 slave node 保存了 rdb 以後,再將新的寫命令複製給 slave node。
  • 若是在複製期間,內存緩衝區持續消耗超過 64MB,或者一次性超過 256MB,那麼中止複製,複製失敗。
client-output-buffer-limit slave 256MB 64MB 60
  • slave node 接收到 rdb 以後,清空本身的舊數據,而後從新加載 rdb 到本身的內存中,同時基於舊的數據版本對外提供服務。
  • 若是 slave node 開啓了 AOF,那麼會當即執行 BGREWRITEAOF,重寫 AOF。

增量複製

  • 若是全量複製過程當中,master-slave 網絡鏈接斷掉,那麼 slave 從新鏈接 master 時,會觸發增量複製。
  • master 直接從本身的 backlog 中獲取部分丟失的數據,發送給 slave node,默認 backlog 就是 1MB。
  • master 就是根據 slave 發送的 psync 中的 offset 來從 backlog 中獲取數據的。

Heartbeat

主從節點互相都會發送 heartbeat 信息。

master 默認每隔 10秒 發送一次 heartbeat,slave node 每隔 1秒 發送一個 heartbeat。

異步複製

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

Redis 如何才能作到高可用

若是系統在 365 天內,有 99.99% 的時間,都是能夠嘩嘩對外提供服務的,那麼就說系統是高可用的。

一個 slave 掛掉了,是不會影響可用性的,還有其它的 slave 在提供相同數據下的相同的對外的查詢服務。

可是,若是 master node 死掉了,會怎麼樣?無法寫數據了,寫緩存的時候,所有失效了。slave node 還有什麼用呢,沒有 master 給它們複製數據了,系統至關於不可用了。

redis 的高可用架構,叫作 failover 故障轉移,也能夠叫作主備切換。

master node 在故障時,自動檢測,而且將某個 slave node 自動切換爲 master node 的過程,叫作主備切換。這個過程,實現了 redis 的主從架構下的高可用。

後面會詳細說明 redis 基於哨兵的高可用性


本文的重點是你有沒有收穫與成長,其他的都不重要,但願讀者們能謹記這一點。同時我通過多年的收藏目前也算收集到了一套完整的學習資料,包括但不限於:分佈式架構、高可擴展、高性能、高併發、Jvm性能調優、Spring,MyBatis,Nginx源碼分析,Redis,ActiveMQ、、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多個知識點高級進階乾貨,但願對想成爲架構師的朋友有必定的參考和幫助

須要更詳細架構師技能思惟導圖和如下資料的能夠加一下技術交流分享羣:「708 701 457」免費獲取




相關文章
相關標籤/搜索