1. 程式人生 > >老司機帶你玩轉面試(3):Redis 高可用之主從模式

老司機帶你玩轉面試(3):Redis 高可用之主從模式

![](https://cdn.geekdigging.com/Interview/mianshi_header_1.jpg) ## 前文回顧 建議前面文章沒看過的同學先看下前面的文章: [「老司機帶你玩轉面試(1):快取中介軟體 Redis 基礎知識以及資料持久化」](https://www.geekdigging.com/2020/07/12/2878870968/) [「老司機帶你玩轉面試(2):Redis 過期策略以及快取雪崩、擊穿、穿透」](https://www.geekdigging.com/2020/07/12/1506238325/) ## Redis 主從模式 在生產環境使用 Redis ,完全禁止使用單機模式,單機模式風險太高,一臺機器出於某些原因掛掉,就會導致整個快取服務死掉,所以,我們需要使用多臺機器來保證 Redis 的高可用,同時也順便提升了併發性。 對於 Redis 快取而言,更常見的應用場景是支援讀高併發,而寫高併發的場景相對比較少(不能說沒有,只能說相對讀高併發比較少)。 因此,使用主從模式,一主多從,主負責寫,並且將資料複製到其它的 slave 節點,從節點負責讀。所有的讀請求全部走從節點。這樣也可以很輕鬆實現水平擴容,支撐讀高併發。 經典的主從模式架構圖如下: ![](https://cdn.geekdigging.com/Interview/redis-master-slave.png) ### 主從同步策略: master 和 slave 剛剛連線的時候,進行全量同步。全量同步結束後,進行增量同步。 當然,如果有需要,slave 在任何時候都可以發起全量同步。redis 策略是,無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。 ### 全量同步: master 執行 BGSAVE 命令,生成一個 RDB 檔案, 傳送給 slave , slave 載入 RDB 檔案達到與 master 維持一致。 ![](https://cdn.geekdigging.com/Interview/master-slave-async.png) 1. slave 連線 master 後,傳送 SYNC 命令。 2. master 接收到 SYNC 命名後,開始執行 BGSAVE 生成 RDB 檔案,並使用緩衝區記錄此後執行的所有寫命令。 3. master BGSAVE 執行完後,向所有 slave 傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令。 4. slave 收到快照檔案後丟棄所有舊資料,載入收到的快照。 5. master 快照發送完畢後開始向 slave 傳送緩衝區中的寫命令。 6. salve 完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令。 7. 第一次全量同步完成。 ### 增量同步 Redis 增量複製是指 slave 初始化後開始正常工作時 master 發生的寫操作同步到 slave 的過程。 增量複製的過程主要是 master 每執行一個寫命令就會向 slave 傳送相同的寫命令,從伺服器接收並執行收到的寫命令。 ### 心跳資訊 主從節點互相都會發送心跳資訊。 master 預設每隔 10 秒傳送一次心跳資訊,slave 每隔 1 秒傳送一個心跳資訊。 ### 注意點: * Redis 使用非同步的方式將資料從 master 節點複製到 slave 節點,slave 會週期性地確認自己每次複製的資料量。 * slave 做複製的時候,不會 block master 正常工作。 * slave 做複製的時候,也不會 block 自己當前的查詢工作,只是查詢的時候依然會使用舊資料,等到複製完成後,需要刪除老資料載入新資料的時候才會 block 當前的查詢工作。 * slave 主要用來做橫向擴容,提升讀的吞吐量,一定程度上做到了讀的高可用。 * slave 不一定要連線到 master ,也可以 slave 連線到 slave 。 * slave 不會處理過期 key ,只會等待 master 過期 key。如果 master 過期了一個 key,或者通過 LRU 淘汰了一個 key,那麼會模擬一條 del 命令傳送給 slave。 ### 無磁碟化主從複製 master 節點可以在記憶體中直接建立 RDB 檔案,然後將 RDB 檔案直接傳送給 salve 節點,不在自己本地落地到磁碟,這個操作只需要在配置檔案中開啟 `repl-diskless-sync yes` 。 但是這樣做的風險會比較高,因此,強烈建議在 master 上開啟持久化服務。 如果一定要在 master 節點上設定不開啟持久化,請在確保 Redis 例項不會自動重啟。 **為啥要確保例項不會自動重啟?** 下面給大家分享一個案例,這是生產環境真實發生過的事情,都是血的教訓。 一個主從結構的 Redis 叢集,當 master 沒有配置開啟資料持久化,某個時間,突然 master 節點宕機,然後自動重啟,當 master 節點自動重啟後,由於沒有開啟資料持久化,這時的 master 節點中是無資料的,當 salve 節點進行資料同步的時候,會把 salve 節點的資料也做清空操作。這時,整個主從結構的 Redis 叢集全都沒有資料,大量的請求過來發現 Redis 沒有資料,導致請求落到了 DB 上,結果是毀滅性的。 主從模式存在的問題是,它僅僅只做到了讀高可用,如果一旦 master 節點掛掉了,就沒辦法寫資料了,只剩下 slave 節點還能讀資料,但是資料同步也沒有了,只能靠人工干預進行恢復,這並不是我們想要的高可用。 我們還需要寫高可用,這就引出了 Redis 的高可用架構:哨兵模式。 簡單來講,哨兵模式就是在 master 節點不可用後,可以自發的進行主備切換,或者叫做故障轉移。 master 節點在發生故障後,整個叢集可以自動檢測,將某個 salve 自動切換成 master 節點,這種模式才算是實現了 Redis 真正意義上的高可用。 ## 參考 https://www.cnblogs.com/daofaziran/p/10978