天天看點

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

在Redis服務中,保證服務高可用是非常重要的,除了保證提供正常服務(如主從分離、快速容災技術),還需要考慮資料容量的擴充、資料安全不會丢失等。

Redis中,實作高可用的技術主要包括:

  • 持久化:單機備份問題,最簡單的高可用方法;主要作用是資料備份到磁盤,保證不會因為Redis程序退出而資料丢失。
  • 主從複制:資料多機熱備,高可用Redis的基礎;哨兵和叢集都是在複制基礎上實作高可用的;複制實作了資料的多機備份、讀的負載均衡、簡單的故障恢複。缺陷:故障恢複無法自動化、寫操作無法負載均衡、存儲能力受到單機的限制。
  • 哨兵:在複制的基礎上,哨兵實作了自動化的故障恢複。缺陷:寫操作無法負載均衡;存儲能力受到單機的限制。
  • 叢集:通過叢集,Redis解決了寫的負載均衡,以及存儲能力的單機限制、容量擴充等問題,實作了較為完善的高可用方案。

一、Redis主從複制

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題
  • 将Master主節資料同步到多個Slave,當Master節點或者其他節點出現當機後,Redis服務還可以使用。
  • Redis為了保持從節點資料一緻性,主從之間采用讀寫分離,可以避免主從都處理寫操作,進行加鎖等一系列開銷。

讀操作:主從庫都可以執行;

寫操作:先在主庫執行,再由主庫将寫操作同步給從庫。

主庫資料同步從庫的方式有兩種:全量同步+增量同步

1、全量同步

通常是主從伺服器剛剛連接配接的時候,會先進行全量同步。

  1. 從庫啟動,發生給主庫PSYN指令進行資料同步請求(指令包含主庫的runID和複制進度offset兩個位移參數);
  2. 主庫處理PSYNC指令,儲存RDB檔案發送給從庫,發送期間會使用複制緩存區(replication buffer)記錄後續的所有寫操作;
  3. 從庫收到資料後,會先清空目前資料庫,然後加載從主庫擷取的RDB 檔案;
  4. 主庫完成 RDB 檔案發送後,也會将儲存發送RDB檔案期間寫操作的replication buffer發給從庫,從庫再重新執行這些操作。這樣一來,主從庫就實作同步了。
Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

 為了分擔主庫生成 RDB 檔案和傳輸 RDB 檔案壓力,提高效率,可以使用 “主 - 從 - 從”模式将主庫生成 RDB 和傳輸 RDB 的壓力,以級聯的方式分散到從庫上。

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

2、增量同步

一般在全量同步結束後,進行增量同步,或主從庫間網絡斷,再進行資料同步。

基于環形緩沖區repl_backlog_buffer緩存區(複制積壓緩沖區)實作,主庫會記錄自己寫到的位置master_repl_offset ,從庫則會記錄自己已經讀到的位置slave_repl_offset, 主庫并通過master_repl_offset 和 slave_repl_offset的內插補點的資料同步到從庫。

環形緩沖區:在緩沖區寫滿後,主庫會繼續寫入,覆寫掉之前寫入的操作。如果從庫的讀取速度比較慢,就有可能導緻從庫還未讀取的操作被主庫新寫的操作覆寫了,這會導緻主從庫間的資料不一緻,造成主從節點間重新開始執行全量複制。是以需要關注 repl_backlog_size參數,調整合适的緩沖空間大小,避免資料覆寫,主從資料不一緻。

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

主從庫間網絡斷了, 主從庫會采用增量複制的方式繼續同步,主庫會把斷連期間收到的寫操作指令,寫入 replication buffer,同時也會把這些操作指令也寫入 repl_backlog_buffer 這個緩沖區,然後主庫并通過master_repl_offset 和 slave_repl_offset的內插補點資料同步到從庫。 

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

二、Redis哨兵機制

Redis提供了哨兵機制,哨兵為運作在特殊模式下的 Redis 程序。

哨兵機制是實作主從庫自動切換的關鍵機制,其主要分為三個階段:

  • 監控:哨兵程序會周期性地給所有的主從庫發送 PING 指令,檢測它們是否仍然線上運作;
  • 選主:主庫挂了以後,哨兵基于一定規則評分機制選舉出一個從庫執行個體作為新的主庫 ;
  • 通知 :哨兵會将新主庫的資訊發送給其他從庫,讓它們和新主庫建立連接配接,并進行資料複制。同時,哨兵會把新主庫的資訊廣播通知給用戶端,讓它們把請求操作發到新主庫上;
Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

哨兵的監控是如何判斷主從庫下線狀态:

  • 主觀下線: 哨兵程序用 PING 指令檢測它自己和主從庫的網絡連接配接情況,用來判斷執行個體的狀态, 如果當哨兵發現主庫或從庫對 PING 指令的響應逾時了,那麼哨兵就會先把它标記為"主觀下線"。
  • 客觀下線:哨兵叢集中,基于少數服從多數,多數哨兵都判定主庫已"主觀下線",數量大于N/2+1(可以自定義設定阙值)則認為主庫"客觀下線"。

單機哨兵容易誤判,誤判後主從切換産生額外開銷,為了避免誤判,是以采用哨兵叢集,多個哨兵一起監控,基于少數服從多數原則,主觀下線到客觀下線;

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

哨兵之間是如何互相通信:

基于 Redis 提供的釋出 / 訂閱機制(pub/sub 機制) ,在主庫上有一個名為“__sentinel__:hello”的頻道,不同哨兵通過它來釋出/訂閱消息,實作互相通信;而且隻有訂閱了同一個頻道的應用,才能通過釋出的消息進行資訊交換。

  • 哨兵 1連接配接相關資訊(IP端口)釋出到主庫“__sentinel__:hello”頻道上,哨兵 2 和 3 訂閱該頻道。
  • 哨兵 2 和 3 就可以從這個頻道直接擷取哨兵 1連接配接資訊,以這樣的方式哨兵叢集就形成了,實作各個哨兵互相通信。
Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題

哨兵之間是如何選主:

新主庫選舉按照 一定條件篩選出的符合條件的從庫,并按照 一定規則對其進行打分,最高分者為新主庫。基于某一輪評出最高分從庫就選舉結束,哨兵發起主從切換。

一定條件包括:

  • 從庫的目前線上狀态
  • 判斷它之前的網絡連接配接狀态,通過down-after-milliseconds * num(斷開連接配接次數),當斷開連接配接次數超過門檻值,不适合為新主庫。

一定規則包括:

  • 從庫優先級 , 通過slave-priority 配置項,給不同的從庫設定不同優先級,優先級最高的從庫得分高;
  • 從庫複制進度,和舊主庫同步程度最接近的從庫得分高,通過repl_backlog_buffer緩沖區記錄主庫 master_repl_offset 和從庫slave_repl_offset 相差最小高分;
  • 從庫 ID 号 , ID 号小的從庫得分高。

選舉完新的主庫後,不能每個哨兵都發起主從切換,需要選舉成leader哨兵,才能執行主從切換;也基于少數服從多數原則"投票仲裁"選舉出來,當任何一個哨兵判定主庫“主觀下線”後,發送 s-master-down-by-addr指令想要成為Leader的信号,其他哨兵根據與主機連接配接情況作出相對的響應,贊成票Y,反對票N,而且如果有多個哨兵發起請求,每個哨兵的贊成票隻能投給其中一個,其他隻能為反對票。

成為Leader哨兵滿足兩個條件:

  1. 獲得半數以上的贊成票;
  2. 獲得的票數同時還需要大于等于哨兵配置檔案中的quorum值。

Leader哨兵發送消息主從庫切換,端戶端就會接收到新主庫的連接配接資訊:

switch-master <master name> <oldip> <oldport> <newip> <newport>
           

三、Redis叢集

叢集(Redis Cluster),是Redis 3.0開始引入的分布式存儲方案。

  • 由多個節點(Node)組成,Redis的資料分布在這些節點中,突破了Redis單機記憶體大小的限制,存儲容量大大增加;
  • 叢集中的節點分為主節點和從節點:隻有主節點負責讀寫請求!!和叢集資訊的維護;從節點負責高可用,隻進行主節點資料和狀态資訊的複制。
  • 叢集支援主從複制和主節點的自動故障轉移(故障轉移的選舉有所有主節點進行,與哨兵類似);當任一節點發生故障時,叢集仍然可以對外提供服務。

四、資料問題

1、主備切換後, 異步複制導緻的少量資料丢失

主從資料在異步複制過程中,master有部分資料還沒複制到slave就當機了,則未同步這部分資料就丢失了

2、主從複制的過程,異步複制導緻資料不一緻

在主從異步複制過程中,當從庫因為網絡延遲或執行複雜度高指令阻塞導緻滞後執行同步指令,這樣就會導緻資料不一緻;

解決方法:

可以開發一個外部程式來監控主從庫間的複制進度(master_repl_offset 和 slave_repl_offset ),通過監控 master_repl_offset 與slave_repl_offset內插補點得知複制進度,當複制進度不符合預期設定的Client不再從該從庫讀取資料。

Redis高可用(一)- 概述一、Redis主從複制二、Redis哨兵機制三、Redis叢集四、資料問題