天天看點

redis 哨兵_Redis叢集&哨兵機制

redis 哨兵_Redis叢集&哨兵機制

Redis主從複制

什麼是主從複制

​ 持久化保證了即使 Redis 服務重新開機也不會丢失資料,因為 Redis 服務重新開機後會将硬碟上持久化的資料恢複到記憶體中,但是當 Redis 伺服器的硬碟損壞了可能會導緻資料丢失,不過通過 Redis 的主從複制機制就可以避免這種單點故障。

實作原理

  • Redis 的主從同步,分為 全量同步 增量同步
  • 隻要從機第一次連接配接上主機是 全量同步
  • 斷線重連有可能觸發 全量同步 也有可能是 增量同步 ( master 判斷 runid 是否一緻)。
  • 除此之外的情況都是 增量同步

全量同步

​ Redis

的全量同步過程主要分三個階段:
  • 從伺服器連接配接主伺服器,發送同步指令。
  • 主伺服器接收到同步命名後,開始執行BGSAVE指令生成RDB檔案并使用緩沖區記錄此後執行的所有寫指令。
  • 主伺服器BGSAVE執行完後,向所有從伺服器發送快照檔案,并在發送期間繼續記錄被執行的寫指令。
  • 從伺服器收到快照檔案後,載入解析快照,完成資料同步。
redis 哨兵_Redis叢集&哨兵機制

增量同步

  • Redis 增量同步主要指 Slave 完成初始化後開始正常工作時, Master 發生的寫操作同步到 Slave 的過程
  • 通常情況下, Master 每執行一個寫指令就會向 Slave 發送相同的 寫指令 ,然後 Slave 接收并執行。

``` # replicaof # 表示目前【從伺服器】對應的【主伺服器】的IP是192.168.10.135,端口是6379。 #4.0之前隻能slaveof 4.0之後預設replicaof,slaveof都起作用

slaveof 192.168.133.154 6379

replicaof 192.168.133.154 6379 ```

Redis 哨兵機制

什麼是哨兵

​ Redis Sentinel是一個分布式系統,為Redis提供高可用性解決方案。可以在一個架構中運作多個 Sentinel 程序(progress), 這些程序使用流言協定(gossip protocols)來 接收關于主伺服器是否下線的資訊, 并使用投票協定(agreement protocols)來決定是否執行自動故 障遷移, 以及選擇哪個從伺服器作為新的主伺服器。

​ Redis 的 Sentinel 系統用于管理多個 Redis 伺服器(instance) 該系統執行以下三個任務:

  • 監控(Monitoring) : Sentinel 會不斷地定期檢查你的主伺服器和從伺服器是否運作正常。
  • 提醒(Notification) : 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以通過 API 向管理者或者其他應用程式發送通知。
  • 自動故障遷移(Automaticfailover) : 當一個主伺服器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會将失效主伺服器的其中 一個從伺服器更新為新的主伺服器, 并讓失效主伺服器的其他從伺服器改為複制新的主伺服器; 當客 戶端試圖連接配接失效的主伺服器時, 叢集也會向用戶端傳回新主伺服器的位址, 使得叢集可以使用新主 伺服器代替失效伺服器。

哨兵配置

sentinel.conf

# 設定端口 
port 26379 

# 是否守護程序啟動 
daemonize yes

# 守護程序運作的時候需要保留pidfile 
pidfile /var/run/redis-sentinel.pid 

# 日志檔案 
logfile "/root/log/sentinel.log" 

## sentinel monitor master-group-name hostname port quorum 
## quorum的解釋如下: 
##(1)至少多少個哨兵要一緻同意,master程序挂掉了,或者slave程序挂掉了,或者要啟動一個 
#故障轉移操作 
##(2)quorum是用來識别故障的,真正執行故障轉移的時候,還是要在哨兵叢集執行選舉,選舉一 個哨兵程序出來執行故障轉移操作 
##(3)假設有5個哨兵,quorum設定了2,那麼如果5個哨兵中的2個都認為master挂掉了; 2個哨 兵中的一個就會做一個選舉,選舉一個哨兵出來,執行故障轉移; 如果5個哨兵中有3個哨兵都是運作 的,那麼故障轉移才會被允許執行。 
# 原文是:Note that whatever is the ODOWN quorum, a Sentinel will require to 
# be selected by the majority of the known Sentinels in order to 
# start a failover, so no failover can be performed in minority. 
sentinel monitor mymaster 127.0.0.1 6379 3 

# down-after-milliseconds,超過多少毫秒跟一個redis執行個體斷了連接配接(ping不通),哨兵就可 能認為這個redis執行個體挂了 
sentinel down-after-milliseconds mymaster 30000 

# parallel-syncs,新的master别切換之後,同時有多少個slave被切換到去連接配接新master,重 新做同步,數字越低,花費的時間越多 

# 比如:master當機了,4個slave中有1個切換成了master,剩下3個slave就要挂到新的master 上面去 

# 這個時候,如果parallel-syncs是1,那麼3個slave,一個一個地挂接到新的master上面去,1 個挂接完,而且從新的master sync完資料之後,再挂接下一個。 

# 如果parallel-syncs是3,那麼一次性就會把所有slave挂接到新的master上去 
sentinel parallel-syncs mymaster 1 

#failover-timeout,執行故障轉移的timeout逾時時長,Default is 3 minutes.
sentinel failover-timeout mymaster 180000 

#如果主節點設定了密碼,則需要這個配置,否則哨兵無法對主節點進行監控。
sentinel auth-pass mymaster password
           

為什麼要用到哨兵

哨兵(Sentinel)主要是為了解決在主從複制架構中出現當機的情況,主要分為兩種情況:

  1. 從Redis當機

在Redis中從庫重新啟動後會自動加入到主從架構中,自動完成同步資料。在Redis2.8版本後,主從斷線後恢複的情況下實作增量複制。

  1. 主Redis當機

需要以下2步才能完成: a. 在從資料庫中執行SLAVEOF NO ONE指令,斷開主從關系并且提升為主庫繼續服務。 b. 将主庫重新啟動後,執行SLAVEOF指令,将其設定為其他庫的從庫,這時資料就能更新回來。

由于這個手動完成恢複的過程其實是比較麻煩的并且容易出錯,是以Redis提供的哨兵(sentinel)的功能來解決

  1. 哨兵機制的高可用

Sentinel(哨兵)是Redis 的高可用性解決方案:由一個或多個Sentinel 執行個體 組成的Sentinel 系統可以監視任意多個主伺服器,以及這些主伺服器屬下的所有從伺服器,并在被監視的主伺服器進入下線狀态時,自動将下線主伺服器屬下的某個從伺服器更新為新的主伺服器。

如圖

redis 哨兵_Redis叢集&哨兵機制
在Server1 掉線後:
redis 哨兵_Redis叢集&哨兵機制
更新Server2 為新的主伺服器:
redis 哨兵_Redis叢集&哨兵機制

哨兵的定時監控

​ 任務1:每個哨兵節點每10秒會向主節點和從節點發送info指令擷取最拓撲結構圖,哨兵配置時隻要配置對主節點的監控即可,通過 向主節點發送info,擷取從節點的資訊,并當有新的從節點加入時可以馬上感覺到。

redis 哨兵_Redis叢集&哨兵機制

​ 任務2:每個哨兵節點每隔2秒會向redis資料節點的指定頻道上發送該哨兵節點對于主節點的判斷以及目前哨兵節點的資訊,同時每個 哨兵節點也會訂閱該頻道,來了解其它哨兵節點的資訊及對主節點的判斷,其實就是通過消息publish和subscribe來完成的。

redis 哨兵_Redis叢集&哨兵機制

​ 任務3:每隔1秒每個哨兵會向主節點、從節點及其餘哨兵節點發送一次ping指令做一次心跳檢測,這個也是哨兵用來判斷節點是否正常 的重要依據。

redis 哨兵_Redis叢集&哨兵機制

主觀下線

所謂主觀下線,就是單個sentinel認為某個服務下線(有可能是接收不到訂閱,之間的網絡不通等等原因)。

sentinel會以每秒一次的頻率向所有與其建立了指令連接配接的執行個體(master,從服務,其他sentinel)發ping指令,通過判斷ping回複是有效回複,還是無效回複來判斷執行個體時候線上(對該sentinel來說是“主觀線上”)。

sentinel配置檔案中的down-after-milliseconds設定了判斷主觀下線的時間長度,如果執行個體在down-after-milliseconds毫秒内,傳回的都是無效回複,那麼sentinel回認為該執行個體已(主觀)下線,修改其flags狀态為SRI_S_DOWN。如果多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不同,這個在實際生産中要注意。

客觀下線

當主觀下線的節點是主節點時,此時該哨兵3節點會通過指令sentinel is-masterdown-by-addr尋求其它哨兵節點對主節點的判斷,如果其他的哨兵也認為主節點主觀線下了,則當認為主觀下線的票數超過了quorum(選舉)個數,此時哨兵節點則認為該主節點确實有問題,這樣就客觀下線了,大部分哨兵節點都同意下線操作,也就說是客觀下線

redis 哨兵_Redis叢集&哨兵機制

哨兵lerder選舉流程

如果主節點被判定為客觀下線之後,就要選取一個哨兵節點來完成後面的故障轉移工作,選舉出一個leader的流程如下:

​ a)每個線上的哨兵節點都可以成為上司者,當它确認(比如哨兵3)主節點下線時,會向其它哨兵發is-master-down-by-addr指令,征 求判斷并要求将自己設定為上司者,由上司者處理故障轉移。 ​ b)當其它哨兵收到此指令時,可以同意或者拒絕它成為上司者。 ​ c)如果哨兵3發現自己在選舉的票數大于等于num(sentinels)/2+1時,将成為上司者,如果沒有超過,繼續選舉…………

redis 哨兵_Redis叢集&哨兵機制

自動故障轉移機制

在從節點下選擇新的節點

sentinel狀态資料結構中儲存了主服務的所有從服務資訊,領頭sentinel按照如下的規則從從服務清單中挑選出新的主服務

  • 過濾掉主觀下線的節點。
  • 選擇slave-priority(優先級)最高的節點,如果由則傳回沒有就繼續選擇。
  • 選擇出複制偏移量最大的系節點,因為複制便宜量越大則資料複制的越完整,如果由就傳回了,沒有就繼續。
  • 選擇run_id最小的節點
redis 哨兵_Redis叢集&哨兵機制

更新主從狀态

通過slaveof no one指令,讓選出來的從節點成為主節點;并通過slaveof指令讓其他節點成為其從節點。

将已下線的主節點設定成新的主節點的從節點,當其回複正常時,複制新的主節點,變成新的主節點的從節點

同理,當已下線的服務重新上線時,sentinel會向其發送slaveof指令,讓其成為新主的從。

Sentinel的工作原理總結

  1. 每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 執行個體發送一個 PING 指令。
  2. 如果一個執行個體(instance)距離最後一次有效回複 PING 指令的時間超過 down-after-milliseconds 選項所指定的值, 則這個執行個體會被 Sentinel 标記為主觀下線。
  3. 如果一個Master被标記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率确認Master的确進入了主觀下線狀态。
  4. 當有足夠數量的 Sentinel(大于等于配置檔案指定的值)在指定的時間範圍内确認Master的确進入了主觀下線狀态, 則Master會被标記為客觀下線 。
  5. 在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave發送 INFO 指令 。
  6. 當Master被 Sentinel 标記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 發送 INFO 指令的頻率會從 10 秒一次改為每秒一次 。
  7. 若沒有足夠數量的 Sentinel 同意 Master 已經下線, Master 的客觀下線狀态就會被移除。 Redis叢集&哨兵機制Redis叢集&哨兵機制

繼續閱讀