1. 程式人生 > >Redis Sentinel基本介紹(翻譯以及總結)

Redis Sentinel基本介紹(翻譯以及總結)

目錄

Redis Sentinel翻譯文件(2015.12.25)

Redis Sentinel介紹

Redis Sentinel 為Redis提供了高可用的實現。通俗來說就是你可以部署一套無需人為干預即可防災的Redis環境。
RS同時為客戶端提供了其他諸如監控,通知的功能。

從全域性來說RS的功能如下:

  • 監控: RS時刻監控主從是否在正常工作。
  • 通知: 當某個Redis例項出現問題,RS可以通知系統管理員或者通過API通知其他程式。
  • 自動切換: 如果一個主例項失效,RS會啟動一個失效轉移(從升級為主)的程序,其他的從節點將重新跟隨新的主節點。連線到RedisServer的會被通知切換到新的地址。
  • 配置提供者: RS充當了客戶端服務自動發現的提供者:連線到Sentinal的客戶端,Sentianl會響應最新的主節點地址給客戶端,並且當發生轉移的時候會發送通知。

分散式的Redis Sentinel

Redis sentinel是一個分散式的系統。
它執行在有多個Sentinel協調工作的環境中,多個Sentinel協調工作的好處如下:

  • 當一個master不可用後,多個Sentinel共同決定後才執行故障檢測,減少了錯誤判斷的機率。
  • 即使有失效Sentinel節點,系統依然健壯的工作。沒有故障轉移的單點系統畢竟毫無意義。

所有的Sentinel,Redis例項(主從)以及連線到Sentinel和Reids的客戶端,同時組成了一個大型的分散式系統。本文將逐步從基本配置使得可以理解Sentinel的基本屬性講起,到更多的綜合介紹(可選的)以便理解Sentinel是如何工作的。

快速開始

獲取Sentinel

目前的Sentinel版本是Sentinel 2,用了更健壯和簡單的預測演算法重寫了最初的版本。
Redis Sentinel的穩定版本嵌入在Redis2.8和3.0版本中。這兩個都是目前最新的版本。新的版本正在不穩定的分支上進行開發,當確認這些新特性已經穩定後會儘快移植到2.8以及3.0。
Redis Sentinel1,嵌入在Redis2.6中,已經不推薦使用。

啟動Sentinel

如果你在使用redis-sentinel的可執行檔案(或者redis-server),你可以用下面的命令來啟動redis-sentinal

redis-sentinel /path/to/sentinel.conf

同時你可以用redis-server以sentinel模式啟動

redis-server /path/to/sentinel.conf --sentinel

這兩種方式是一樣的。
但是這兩種方式都必須顯示宣告配置檔案,這個檔案將在重啟的時候被用來儲存快照以便重新載入。如果未提供配置檔案或者提供的配置檔案不可寫,系統將直接拒絕啟動。
系統執行中預設繫結的監聽埠是26379,所以為了Sentinel正常工作,機器的26379埠必須開啟以便接收其他Sentinel例項的連線。不然Sentinel就無法應答請求,導致故障轉移無法進行。

部署Sentinel的基本要求

  1. 一個健壯的環境你需要至少三個Sentinel節點。
  2. 安裝在電腦或者虛擬機器下的三個例項應該在不同的方式下失效,舉個例子,用多個不同的物理機或者用虛擬機器不同的可用區域。
  3. Redis+Sentinel的分散式系統在Redis非同步複製期間,不能保證保留在失敗期間收到的寫請求。
  4. 你需要Sentinel客戶端的支援,大部分流行的客戶端都有,但並不是所有。
  5. 你必須經過大量的測試來確認HA是安全可用的。否則當你發現時已經遲了。
  6. Sentinel和Docker混合使用的時候應該注意:Docker執行的Sentinel重對映,破壞了Sentinel的自動發現。稍後會詳細講解。

配置Sentinel

Redis原始檔包含了一個可以啟動sentinel叫做sentinel.conf的檔案,但是一個典型的最小配置如下:

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5

你只需要指定監控的master,給每個master(可能包含不定的slave)一個不同的名稱。slave是自動發現的,所以無需指定。當追加新的節點後,Sentinel會自動更新配置。當故障期間slave升級為master或者一個新的sentinel被發現後,也會自動更新配置。重啟後將會使用新的配置。

sentinel monitor宣告的含義如下:

sentinel monitor <master-group-name> <ip> <port> <quorum>

為了清晰起見,讓我們逐行分析分析檔案:
第一行是用來告訴Redis監控一個叫做mymaster的master,ip地址為127.0.0.1以及埠是6379,quorum為2。除了quorum(票數)以外,一切都顯而易見:

  • quorum是需要確認master失效的Setinel的數量,為了確認master已經失效(訪問網路阻塞引起的誤報),而後啟動一個failover的程序(但是並不會馬上開始,需要其他Sentinel的同意)。
  • quorum僅僅用來確認是否故障。為了故障轉移,多個Sentinel需要選舉出新的master。

舉例來說,如果你有五個Sentinel程序,而且quorum設定了2,表現如下:

  • 如果兩個Sentinel同時同意了master失效,兩個中的一個將開始程序故障轉移。
  • 如果至少有三個Sentinel是可用的,failover將被通過並且真正開始啟動。

例如,叢集中有5個sentinel,票數被設定為2,當2個sentinel認為一個master已經不可用了以後,將會觸發failover,但是,進行failover的那個sentinel必須先獲得至少3個sentinel的授權才可以實行failover。
如果票數被設定為5,要達到ODOWN狀態,必須所有5個sentinel都主觀認為master為不可用,要進行failover,那麼得獲得所有5個sentinel的授權。這就是說大多數。

實際上這是說在故障期間,如果多數Sentinel不能響應,將無法啟動故障轉移的程序。

其他的Sentinel選項

其他選項基本如下:

sentinel <option_name> <master_name> <option_value>

用途如下:

  • down-after-milliseconds是Sentinel詢問一個例項是否宕掉(包含不能響應Ping或者響應錯誤)的超時時間。
  • parallel-syncs設定了故障轉移時候同時重新同步新的master的slave數量。這個數量越小,故障轉移花費的時間將越長。但是如果你希望從同時提供資料,就不能將所有的slave同時去複製資料。可以通過將這個值設為 1 來保證每次只有一個slave處於不能處理命令請求的狀態。

其他配置項在sentinel.conf中都有很詳細的解釋。
所有的配置都可以在執行時用命令SENTINEL SET command動態修改。

其他說明(文件未發現,來自別的文件)

Sentinel的“仲裁會”

前面我們談到,當一個master被sentinel叢集監控時,需要為它指定一個引數,這個引數指定了當需要判決master為不可用,並且進行failover時,所需要的sentinel數量,本文中我們暫時稱這個引數為票數

不過,當failover主備切換真正被觸發後,failover並不會馬上進行,還需要sentinel中的大多數sentinel授權後才可以進行failover。
當ODOWN時,failover被觸發。failover一旦被觸發,嘗試去進行failover的sentinel會去獲得“大多數”sentinel的授權(如果票數比大多數還要大的時候,則詢問更多的sentinel)
這個區別看起來很微妙,但是很容易理解和使用。例如,叢集中有5個sentinel,票數被設定為2,當2個sentinel認為一個master已經不可用了以後,將會觸發failover,但是,進行failover的那個sentinel必須先獲得至少3個sentinel的授權才可以實行failover。
如果票數被設定為5,要達到ODOWN狀態,必須所有5個sentinel都主觀認為master為不可用,要進行failover,那麼得獲得所有5個sentinel的授權。

配置版本號

為什麼要先獲得大多數sentinel的認可時才能真正去執行failover呢?

當一個sentinel被授權後,它將會獲得宕掉的master的一份最新配置版本號,當failover執行結束以後,這個版本號將會被用於最新的配置。因為大多數sentinel都已經知道該版本號已經被要執行failover的sentinel拿走了,所以其他的sentinel都不能再去使用這個版本號。這意味著,每次failover都會附帶有一個獨一無二的版本號。我們將會看到這樣做的重要性。

而且,sentinel叢集都遵守一個規則:如果sentinel A推薦sentinel B去執行failover,B會等待一段時間後,自行再次去對同一個master執行failover,這個等待的時間是通過failover-timeout配置項去配置的。從這個規則可以看出,sentinel叢集中的sentinel不會再同一時刻併發去failover同一個master,第一個進行failover的sentinel如果失敗了,另外一個將會在一定時間內進行重新進行failover,以此類推。

redis sentinel保證了活躍性:如果大多數sentinel能夠互相通訊,最終將會有一個被授權去進行failover.
redis sentinel也保證了安全性:每個試圖去failover同一個master的sentinel都會得到一個獨一無二的版本號。

配置傳播

一旦一個sentinel成功地對一個master進行了failover,它將會把關於master的最新配置通過廣播形式通知其它sentinel,其它的sentinel則更新對應master的配置。

一個faiover要想被成功實行,sentinel必須能夠向選為master的slave傳送SLAVE OF NO ONE命令,然後能夠通過INFO命令看到新master的配置資訊。

當將一個slave選舉為master併發送``SLAVE OF NO ONE```後,即使其它的slave還沒針對新master重新配置自己,failover也被認為是成功了的,然後所有sentinels將會發布新的配置資訊。

新配在叢集中相互傳播的方式,就是為什麼我們需要當一個sentinel進行failover時必須被授權一個版本號的原因。

每個sentinel使用##釋出/訂閱##的方式持續地傳播master的配置版本資訊,配置傳播的##釋出/訂閱##管道是:sentinel:hello。

因為每一個配置都有一個版本號,所以以版本號最大的那個為標準。

舉個栗子:假設有一個名為mymaster的地址為192.168.1.50:6379。一開始,叢集中所有的sentinel都知道這個地址,於是為mymaster的配置打上版本號1。一段時候後mymaster死了,有一個sentinel被授權用版本號2對其進行failover。如果failover成功了,假設地址改為了192.168.1.50:9000,此時配置的版本號為2,進行failover的sentinel會將新配置廣播給其他的sentinel,由於其他sentinel維護的版本號為1,發現新配置的版本號為2時,版本號變大了,說明配置更新了,於是就會採用最新的版本號為2的配置。

這意味著sentinel叢集保證了第二種活躍性:一個能夠互相通訊的sentinel叢集最終會採用版本號最高且相同的配置。

其他細節

sentinel對於不可用有兩種不同的看法,一個叫主觀不可用(SDOWN),另外一個叫客觀不可用(ODOWN)。SDOWN是sentinel自己主觀上檢測到的關於master的狀態,ODOWN需要一定數量的sentinel達成一致意見才能認為一個master客觀上已經宕掉,各個sentinel之間通過命令SENTINEL is_master_down_by_addr來獲得其它sentinel對master的檢測結果。
從sentinel的角度來看,如果傳送了PING心跳後,在一定時間內沒有收到合法的回覆,就達到了SDOWN的條件。這個時間在配置中通過is-master-down-after-milliseconds引數配置。
當sentinel傳送PING後,以下回復之一都被認為是合法的:

PING replied with +PONG.
PING replied with -LOADING error.
PING replied with -MASTERDOWN error.

其它任何回覆(或者根本沒有回覆)都是不合法的。
從SDOWN切換到ODOWN不需要任何一致性演算法,只需要一個gossip協議:如果一個sentinel收到了足夠多的sentinel發來訊息告訴它某個master已經down掉了,SDOWN狀態就會變成ODOWN狀態。如果之後master可用了,這個狀態就會相應地被清理掉。
正如之前已經解釋過了,真正進行failover需要一個授權的過程,但是所有的failover都開始於一個ODOWN狀態。
ODOWN狀態只適用於master,對於不是master的redis節點sentinel之間不需要任何協商,slaves和sentinel不會有ODOWN狀態。

slave自動發現機制

雖然sentinel叢集中各個sentinel都互相連線彼此來檢查對方的可用性以及互相傳送訊息。但是你不用在任何一個sentinel配置任何其它的sentinel的節點。因為sentinel利用了master的釋出/訂閱機制去自動發現其它也監控了統一master的sentinel節點。
通過向名為__sentinel__:hello的管道中傳送訊息來實現。
同樣,你也不需要在sentinel中配置某個master的所有slave的地址,sentinel會通過詢問master來得到這些slave的地址的。
每個sentinel通過向每個master和slave的釋出/訂閱頻道__sentinel__:hello每秒傳送一次訊息,來宣佈它的存在。
每個sentinel也訂閱了每個master和slave的頻道__sentinel__:hello的內容,來發現未知的sentinel,當檢測到了新的sentinel,則將其加入到自身維護的master監控列表中。
每個sentinel傳送的訊息中也包含了其當前維護的最新的master配置。如果某個sentinel發現
自己的配置版本低於接收到的配置版本,則會用新的配置更新自己的master配置。
在為一個master新增一個新的sentinel前,sentinel總是檢查是否已經有sentinel與新的sentinel的程序號或者是地址是一樣的。如果是那樣,這個sentinel將會被刪除,而把新的sentinel新增上去。

Sentinel部署示例

前面你已經瞭解了Sentinel的基本資訊,你可能希望瞭解你應該如何部署Sentinel以及Sentinel應該部署多少個等等問題。下面我們將會用一些例子來講解。

這個環節我們將用文字影象來表示(ASCII art,這個挺好玩)

// 這個代表一個計算機
+--------------------+
| This is a computer |
| or VM that fails   |
| independently. We |
| call it a "box"    |
+--------------------+

// 一個活動中的程序
+-------------------+
| Redis master M1   |
| Redis Sentinel S1 |
+-------------------+

// 兩個通訊的機器

+-------------+               +-------------+
| Sentinel S1 |---------------| Sentinel S2 |
+-------------+               +-------------+

// 斷開連線的機器

+-------------+                +-------------+
| Sentinel S1 |------ // ------| Sentinel S2 |
+-------------+                +-------------+

除此以外:

  • master叫做M1,M2,M3,...,Mn.
  • slaves叫做R1,R2,R3....Rn.
  • Sentinels叫做S1...Sn.
  • clients叫做C1...Cn.
  • 當一個例項被Sentinel改變狀態後,我們把他放入中括號。

因為Sentinel需要多數同意,所以將不會示範僅僅兩個Sentinel的設定。

例子1:只有兩個Sentinel,不要這麼做!

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

Configuration: quorum = 1
  • 這個設定下,如果master M1掛掉,當兩個Sentinel都正常的情況下,R1將會升級為主。這樣看起來似乎是沒有問題的,但是請看下面。
  • 如果M1的那臺機器停止工作了,那麼S1也就掛了。S2無法得到大多數的授權而導致系統不可用。

會演變成下面的情況,造成資料不一致:

+----+           +------+
| M1 |----//-----| [M1] |
| S1 |           | S2   |
+----+           +------+

所以至少使用三個sentinel。

例子2:三個Sentinel

       +----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

Configuration: quorum = 2

M1掛了以後,S2和S3將同意failover。
Slave複製過程中,已經收到的寫請求有丟失的風險。但是上面的風險更大,如下所示:

         +----+
         | M1 |
         | S1 | <- C1 (writes will be lost)
         +----+
            |
            /
            /
+------+    |    +----+
| [M2] |----+----| R3 |
| S2   |         | S3 |
+------+         +----+

M1變成了一個隔離的環境,R2升級為了主。但是C1的請求將會丟失。當M1恢復以後,將丟棄原來的資料,成為新的Master(R2)的從。
因為redis採用的是非同步複製,在這樣的場景下,沒有辦法避免資料的丟失。然而,你可以通過以下配置來配置redis3和redis1,減弱這種情況。

min-slaves-to-write 1
min-slaves-max-lag 10

通過上面的配置,當一個redis是master時,如果它不能向至少一個slave寫資料(上面的min-slaves-to-write指定了slave的數量),它將會拒絕接受客戶端的寫請求。由於複製是非同步的,master無法向slave寫資料意味著slave要麼斷開連線了,要麼不在指定時間內向master傳送同步資料的請求了(上面的min-slaves-max-lag指定了這個時間)。

例子3:Sentinel安裝在客戶端機上

有時候我們僅僅只有兩臺Redis機器,一個主一個從,那麼我們不能按照例2的方式部署,所以我們可以調整如下:

            +----+         +----+
            | M1 |----+----| R1 |
            | S1 |    |    | S2 |
            +----+    |    +----+
                      |
         +------------+------------+
         |            |            |
         |            |            |
      +----+        +----+      +----+
      | C1 |        | C2 |      | C3 |
      | S1 |        | S2 |      | S3 |
      +----+        +----+      +----+

      Configuration: quorum = 2

如上所示,可見的Sentinel和客戶端數量一致,如果一個主可以被大多數的客戶端訪問,那麼他是可用的。客戶端只是普通的Redis應用。
但是可能會C1不可用導致系統無法繼續工作。省略餘下翻譯。

例4:混合型

            +----+         +----+
            | M1 |----+----| R1 |
            | S1 |    |    | S2 |
            +----+    |    +----+
                      |
               +------+-----+
               |            |  
               |            |
            +----+        +----+
            | C1 |        | C2 |
            | S3 |        | S4 |
            +----+        +----+

      Configuration: quorum = 3

Sentinel,Docker,NAT以及其他可能的問題

Docker用了一個埠對映的技術,執行在Docker中的程式可能用了一個我們想象之外的埠,這個對於同時在一臺機器執行多個公用埠的應用很有用處。
Docker不是唯一會導致這種情況的,NAT一樣,甚至包括Ip都會被重新對映。
這導致Sentinel的兩個問題:

  • 無法自動發現其他Sentinel,因為他們基於監聽固定IP埠來發送廣播,但是他們並不能理解remapped以後的IP和埠,所以會錯報無法連線的資訊。
  • 對於從庫來說也有同樣的問題。

你需要用到下面的配置:

sentinel announce-ip <ip>
sentinel announce-port <port>

相關推薦

Redis Sentinel基本介紹翻譯以及總結

目錄 Redis Sentinel翻譯文件(2015.12.25) Redis Sentinel介紹 Redis Sentinel 為Redis提供了高可用的實現。通俗來說就是你可以部署一套無需人為干預即可防災的Redis環境。 RS同時為客戶端提供了其他諸如監控,通知的功能。 從全域性來說RS的功能如下:

大話WEB前端效能優化基本套路關鍵方法總結

https://blog.thankbabe.com/2017/07/05/fore-end-optimize/?utm_source=tuicool&utm_medium=referral 前言 前端效能優化這是一個老生常談的話題,但是還是有很多人沒有真正的

Redis Sentinel的使用基本原理、一主兩從三Sentinel部署、客戶端程式碼使用

Redis Sentinel 1. 基本概念 1.1 背景:主從複製的問題 Redis 的主從複製模式可以將主節點的資料改變同步給從節點,這樣從節點就可以起到兩個用: 第一,作為主節點的一個備份,一旦主節點出了故障不可達的情況,從節點可以作為後備“頂” 上來

Nginx之基本介紹

動靜分離 quit 共享內存 oct bytes err 配置文件 默認頁 日誌格式 這是一篇介紹Nginx基本信息和配置文件詳情的文章,適合入門者,如果你想深入了解Nginx請繞道 什麽是Nginx?   Nginx是輕量級,高性能,跨平臺的web服務器 Nginx的特點

Sharding-JDBC 3.x 原理篇之基本介紹

簡介 Sharding-JDBC是噹噹開源的資料庫水平切分的中介軟體,其代表了客戶端類的分庫分表技術框架(這一點與MyCat不同,MyCat本質上是一種資料庫代理)。Sharding-JDBC定位為輕量級資料庫驅動,由客戶端直連資料庫,以jar包形式提供服務,未

Sharding-JDBC 3.x 原理篇之基本介紹附1.x~3.x版本文件

前言 上一篇描述了Sharding-JDBC的歷史演進過程和設計理念,本篇將具體描述Sharding-Sphere的具體功能和個版本特性。後續將對常用核心功能逐一進行分析和探討。 版本功能 1.x功能列表 分庫分表 SQL解析功能完善,支援聚合,分組,排序,LI

redis sentinel 高可用HA方案部署,及python應用示例

簡介 介紹 redis sentinel(哨兵)叢集的部署,配置一主兩從的redis叢集,並通過 python 程式例項講解通過 redis sentinel 訪問叢集 什麼是哨兵(Sentinel)模式 Redis sentinel 為 Redis 叢集提供了高可

Redis Sentinel原始碼分析

Base 2.8.7在程式碼分析前,先總體介紹下sentinel 的機制。1. 下線定義 sentinel對下線有兩種定義: a.主觀下線(sdown):sentinel例項本身對服務例項的判斷 b.客觀下線(odown):多個sentinel例項對同一個服務SDOWN的狀

SQL資料庫基本介紹

SQL 是用於訪問和處理資料庫的標準的計算機語言。結構化查詢語言(Structured Query Language)簡稱SQL,是一種特殊目的的程式語言,是一種資料庫查詢和程式設計語言,用於存取資料

SAP-MM-PA精解分析系列之基本介紹01-採購基本流程

MM基本知識(01)-採購基本流程        業務舉例:        物料在企業中的採購管理,涉及多種渠道和方式,一般來說,企業的採購一部分來自於外部供應商,一部分來自於自己公司下的其他分支部門。在這些採購過程中,涉及到的部門功能有采購、倉庫管理、發票校驗。     

利用vue重構有贊商城思路以及總結整理

search mod family 綁定 style mon 分發 中間 rev 這個是我的第一個vue項目,歷時了兩個多星期完成吧,通過這個項目了解了vue框架的基本語法以及生命周期等特性,並且了解了vue-loader、vue-cli、vue-router、vuex的

手把手做一個JSP入門程式:程式基本介紹JSP

胡扯   說好的不學jsp,結果今天還是學了。主要還是為了後面的java後臺的學習啦。為了更好的掌握知識,那我們就來寫一個簡單的jsp入門程式吧!這只是一個簡單的入門小程式,所以就沒有太多強大的功能。入門啦,入門啦。對了,由於是作為一個入門程式,所以裡面會有較

redis快取基本介紹

redis快取之NoSQL資料庫基本介紹   NoSQL是以key-value(鍵值對)的形式儲存資料,和傳統的關係型資料庫不一樣,不遵循傳統資料庫的基本要求;例如:SQL標準(select、update、insert、delete)、ASID(事物處理機制transact

Kafka文件2----0.8.2- 基本介紹Getting Start

來源: 說明: 原文中某些專有名詞不做翻譯: kafka topic partition consumer producer server client high-level 1、開始 1.1 介紹kafka可提供分散式、分割槽的、可備份的日誌提交服務,同時也是設計

iOS中執行緒的基本介紹OC

一:pthread:基於C 二:NSThread:基於OC 三:GCD:基於C 四:NSOperation:對GCD面向物件的包裝 (一):GCD基本操作:六種任務執行模式 - (void)touchesBegan:(NSSet<UI

docker-compose安裝redis-sentinel集群1主+2副+2哨兵

after 單機 role monitor refresh docker and byte api 前提:本試驗環境已經提前安裝了docker和docker-compose 說明:本次部署是單機偽集群,想要部署真正的集群,需要將秒個主件拆分到各個機器上去部署,只修改ip地

法那科機器人的基本介紹創建文件

仿真 哇哦 ide image bsp 分享圖片 alt http 仿真軟件 法那科的仿真軟件是基於roboguide運行的,但是黃博主個人認為沒有ABB的軟件好用。當然你使用的好的話可以直接調用大量庫文件,可以省去畫3D圖的時間拉! 安裝完成打開的話,點開新建,出現

Redis Sentinel基本實現原理

一.出現的背景: Redis 主從複製模式下一旦主節點由於故障不能提供服務,需要人工將從節點晉升為主節點,同時還要通知應用方更新主節點地址,對於很多應用這種場景的這種故障處理方式是非常浪費人力的。為了提供Redis主從的高可用性,Redis從2.8版本開始提供Redis Sential(哨兵)架構來解決

Redis 設計與實現第六章 -- 整數集合intset

相同 spa edi redis cnblogs 保存 空間 數值 一個數 概述 1.intset概述 2.intset實現 3.intset升級 intset概述 整數集合是Redis集合鍵的底層實現之一,當值都為整數時,redis就會選擇整數集合作為底層實現。 可以保