Redis的三種叢集方式+穿透與雪崩的預防和解決

java閘瓦發表於2019-04-08

Redis的三種叢集方式概述

1、主從複製

原理

  1. 從伺服器連線主伺服器,傳送SYNC(同步)命令;
  2. 主伺服器接收到SYNC命名後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;
  3. 主伺服器BGSAVE執行完後,向所有從伺服器傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令;
  4. 從伺服器收到快照檔案後丟棄所有舊資料,載入收到的快照;
  5. 主伺服器快照傳送完畢後開始向從伺服器傳送緩衝區中的寫命令;
  6. 從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;(從伺服器初始化完成)
  7. 主伺服器每執行一個寫命令就會向從伺服器傳送相同的寫命令,從伺服器接收並執行收到的寫命令(從伺服器初始化完成後的操作)

優點

  1. 支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離
  2. 為了分載Master的讀操作壓力,Slave伺服器可以為客戶端提供只讀操作的服務,寫服務仍然必須由Master來完成
  3. Slave同樣可以接受其它Slaves的連線和同步請求,這樣可以有效的分載Master的同步壓力。
  4. Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請求。
  5. Slave Server同樣是以非阻塞的方式完成資料同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的資料

缺點

  1. Redis不具備自動容錯和恢復功能,主機從機的當機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。
  2. 主機當機,當機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性。
  3. Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。

2、哨兵模式

原理

當主伺服器中斷服務後,可以將一個從伺服器升級為主伺服器,以便繼續提供服務,但是這個過程需要人工手動來操作。 為此,Redis 2.8中提供了哨兵工具來實現自動化的系統監控和故障恢復功能。

哨兵的作用就是監控Redis系統的執行狀況。它的功能包括以下兩個

(1)監控主伺服器和從伺服器是否正常執行。

(2)主伺服器出現故障時自動將從伺服器轉換為主伺服器。

工作方式

  • 每個Sentinel(哨兵)程式以每秒鐘一次的頻率向整個叢集中的Master主伺服器,Slave從伺服器以及其他Sentinel(哨兵)程式傳送一個 PING 命令。
  • 如果一個例項(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個例項會被 Sentinel(哨兵)程式標記為主觀下線(SDOWN)
  • 如果一個Master主伺服器被標記為主觀下線(SDOWN),則正在監視這個Master主伺服器的所有 Sentinel(哨兵)程式要以每秒一次的頻率確認Master主伺服器的確進入了主觀下線狀態
  • 當有足夠數量的 Sentinel(哨兵)程式(大於等於配置檔案指定的值)在指定的時間範圍內確認Master主伺服器進入了主觀下線狀態(SDOWN), 則Master主伺服器會被標記為客觀下線(ODOWN)
  • 在一般情況下, 每個 Sentinel(哨兵)程式會以每 10 秒一次的頻率向叢集中的所有Master主伺服器、Slave從伺服器傳送 INFO 命令。
  • 當Master主伺服器被 Sentinel(哨兵)程式標記為客觀下線(ODOWN)時,Sentinel(哨兵)程式向下線的 Master主伺服器的所有 Slave從伺服器傳送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
  • 若沒有足夠數量的 Sentinel(哨兵)程式同意 Master主伺服器下線, Master主伺服器的客觀下線狀態就會被移除。若 Master主伺服器重新向 Sentinel(哨兵)程式傳送 PING 命令返回有效回覆,Master主伺服器的主觀下線狀態就會被移除。

優點

  • 哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。
  • 主從可以自動切換,系統更健壯,可用性更高。

缺點

Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。

3、Redis-Cluster叢集

原理

redis的哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每臺redis伺服器都儲存相同的資料,很浪費記憶體,所以在redis3.0上加入了cluster模式,實現的redis的分散式儲存,也就是說每臺redis節點上儲存不同的內容。

Redis-Cluster採用無中心結構,它的特點如下

  1. 所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬。
  2. 節點的fail是通過叢集中超過半數的節點檢測失效時才生效。
  3. 客戶端與redis節點直連,不需要中間代理層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可。

工作方式

在redis的每一個節點上,都有這麼兩個東西,一個是插槽(slot),它的的取值範圍是:0-16383。還有一個就是cluster,可以理解為是一個叢集管理的外掛。當我們的存取的key到達的時候,redis會根據crc16的演算法得出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,通過這個值,去找到對應的插槽所對應的節點,然後直接自動跳轉到這個對應的節點上進行存取操作。

為了保證高可用,redis-cluster叢集引入了主從模式,一個主節點對應一個或者多個從節點,當主節點當機的時候,就會啟用從節點。當其它主節點ping一個主節點A時,如果半數以上的主節點與A通訊超時,那麼認為主節點A當機了。如果主節點A和它的從節點A1都當機了,那麼該叢集就無法再提供服務了

redis中穿透與雪崩的預防及解決

認識快取穿透

快取穿透是指查詢一個一定不存在的資料,由於快取是不命中時需要從資料庫查詢,查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到資料庫去查詢,造成快取穿透。

解決辦法

  • 對所有可能查詢的引數以hash形式儲存,在控制層先進行校驗,不符合則丟棄。還有最常見的則是採用布隆過濾器,將所有可能存在的資料雜湊到一個足夠大的bitmap中,一個一定不存在的資料會被這個bitmap攔截掉,從而避免了對底層儲存系統的查詢壓力。
  • 也可以採用一個更為簡單粗暴的方法,如果一個查詢返回的資料為空(不管是數 據不存在,還是系統故障),我們仍然把這個空結果進行快取,但它的過期時間會很短,最長不超過五分鐘。

認識快取雪崩

如果快取集中在一段時間內失效,發生大量的快取穿透,所有的查詢都落在資料庫上,造成了快取雪崩。

這個沒有完美解決辦法,但可以分析使用者行為,儘量讓失效時間點均勻分佈。大多數系統設計者考慮用加鎖或者佇列的方式保證快取的單執行緒(程式)寫,從而避免失效時大量的併發請求落到底層儲存系統上。

解決方法

  • 在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許一個執行緒查詢資料和寫快取,其他執行緒等待。
  • 可以通過快取reload機制,預先去更新快取,再即將發生大併發訪問前手動觸發載入快取
  • 不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻
  • 做二級快取,或者雙快取策略。A1為原始快取,A2為拷貝快取,A1失效時,可以訪問A2,A1快取失效時間設定為短期,A2設定為長期。

我整理了一些網際網路公司java程式設計師在面試中涉及到的絕大部分架構面試題及答案做成了文件和架構視訊資料免費分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分散式、高併發等架構技術資料)也可以關注獲得更多的面試資料,節省大家收集的時間!

獲取資料的方式:進群 571617441 即可領取!

相關文章