日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redis——sentinel

發布時間:2023/12/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis——sentinel 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是哨兵機制

Redis的哨兵(sentinel)?系統用于管理/多個?Redis?服務器,該系統執行以下三個任務:

·????????監控:?哨兵(sentinel)?會不斷地檢查你的Master和Slave是否運作正常。

·????????提醒:當被監控的某個?Redis出現問題時,?哨兵(sentinel)?可以通過?API?向管理員或者其他應用程序發送通知。

·????????自動故障遷移:當一個Master不能正常工作時,哨兵(sentinel)?會開始一次自動故障遷移操作,它會將失效Master的其中一個Slave升級為新的Master,?并讓失效Master的其他Slave改為復制新的Master;?當客戶端試圖連接失效的Master時,集群也會向客戶端返回新Master的地址,使得集群可以使用Master代替失效Master。

例如下圖所示:

在Server1 掉線后:

升級Server2 為新的主服務器:

哨兵模式修改配置

實現步驟:

1.拷貝到etc目錄

cp sentinel.conf? /usr/local/redis/etc

2.修改sentinel.conf配置文件

sentinel monitor mymast? 192.168.110.133 6379 1? #主節點 名稱 IP 端口號 選舉次數

sentinel auth-pass mymaster 123456?

3. 修改心跳檢測 5000毫秒

sentinel down-after-milliseconds mymaster 5000

4.sentinel parallel-syncs mymaster 2 --- 做多多少合格節點

5. 啟動哨兵模式

./redis-server /usr/local/redis/etc/sentinel.conf --sentinel &


1)Sentinel(哨兵) 進程是用于監控 Redis 集群中 Master 主服務器工作的狀態

2)在 Master 主服務器發生故障的時候,可以實現 Master 和 Slave 服務器的切換,保證系統的高可用(High Availability)

工作方式

1)每個 Sentinel(哨兵)進程以每秒鐘一次的頻率向整個集群中的 Master 主服務器,Slave 從服務器以及其他 Sentinel(哨兵)進程發送一個 PING 命令。

2. 如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel(哨兵)進程標記為主觀下線。

3. 如果一個 Master 主服務器被標記為主觀下線,則正在監視這個 Master 主服務器的所有 Sentinel(哨兵)進程要以每秒一次的頻率確認 Master 主服務器的確進入了主觀下線狀態。

4. 當有足夠數量的 Sentinel(哨兵)進程(大于等于配置文件指定的值)在指定的時間范圍內確認 Master 主服務器進入了主觀下線狀態, 則Master 主服務器會被標記為客觀下線(ODOWN)。

5. 在一般情況下, 每個 Sentinel(哨兵)進程會以每 10 秒一次的頻率向集群中的所有Master 主服務器、Slave 從服務器發送 INFO 命令。

6. 當 Master 主服務器被 Sentinel(哨兵)進程標記為客觀下線時,Sentinel(哨兵)進程向下線的 Master 主服務器的所有 Slave 從服務器發送 INFO 命令的頻率會從 10 秒一次改為每秒一次。

7. 若沒有足夠數量的 Sentinel(哨兵)進程同意 Master 主服務器下線, Master 主服務器的客觀下線狀態就會被移除。若 Master 主服務器重新向 Sentinel(哨兵)進程發送 PING 命令返回有效回復,Master 主服務器的主觀下線狀態就會被移除。

哨兵(sentinel)?的一些設計思路和zookeeper非常類似


我們從啟動并初始化說起

啟動并初始化 Sentinel

啟動一個 Sentinel 可以使用命令:

$ redis-sentinel /path/to/your/sentinel.conf

或者命令:

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

當一個 Sentinel 啟動時, 它需要執行以下步驟:

初始化服務器。

首先, 因為 Sentinel 本質上只是一個運行在特殊模式下的 Redis 服務器, 所以啟動 Sentinel 的第一步, 就是初始化一個普通的 Redis 服務器.

不過, 因為 Sentinel 執行的工作和普通 Redis 服務器執行的工作不同, 所以 Sentinel 的初始化過程和普通 Redis 服務器的初始化過程并不完全相同。

比如說, 普通服務器在初始化時會通過載入 RDB 文件或者 AOF 文件來還原數據庫狀態, 但是因為 Sentinel 并不使用數據庫, 所以初始化 Sentinel 時就不會載入 RDB 文件或者 AOF 文件。

將普通 Redis 服務器使用的代碼替換成 Sentinel 專用代碼。

第二個步驟就是將一部分普通 Redis 服務器使用的代碼替換成 Sentinel 專用代碼。

比如說, 普通 Redis 服務器使用?redis.h/REDIS_SERVERPORT?常量的值作為服務器端口:

#define REDIS_SERVERPORT 6379

而 Sentinel 則使用?sentinel.c/REDIS_SENTINEL_PORT?常量的值作為服務器端口:

#define REDIS_SENTINEL_PORT 26379

為什么在 Sentinel 模式下, Redis 服務器不能執行諸如?SET?、?DBSIZE?、?EVAL?等等這些命令 —— 因為服務器根本沒有在命令表中載入這些命令。

初始化 Sentinel 狀態。

在應用了 Sentinel 的專用代碼之后, 接下來, 服務器會初始化一個?sentinel.c/sentinelState?結構(后面簡稱“Sentinel 狀態”), 這個結構保存了服務器中所有和 Sentinel 功能有關的狀態 (服務器的一般狀態仍然由?redis.h/redisServer?結構保存):

struct sentinelState {// 當前紀元,用于實現故障轉移uint64_t current_epoch;// 保存了所有被這個 sentinel 監視的主服務器// 字典的鍵是主服務器的名字// 字典的值則是一個指向 sentinelRedisInstance 結構的指針dict *masters;// 是否進入了 TILT 模式?int tilt;// 目前正在執行的腳本的數量int running_scripts;// 進入 TILT 模式的時間mstime_t tilt_start_time;// 最后一次執行時間處理器的時間mstime_t previous_time;// 一個 FIFO 隊列,包含了所有需要執行的用戶腳本list *scripts_queue;} sentinel;

初始化 Sentinel 狀態的?masters?屬性

Sentinel 狀態中的?masters?字典記錄了所有被 Sentinel 監視的主服務器的相關信息:

  • 字典的鍵是被監視主服務器的名字。
  • 而字典的值則是被監視主服務器對應的?sentinel.c/sentinelRedisInstance?結構。

每個?sentinelRedisInstance?結構代表一個被 Sentinel 監視的 Redis 服務器實例(instance), 這個實例可以是主服務器、從服務器、或者另外一個 Sentinel 。

實例結構包含的屬性非常多, 以下代碼展示了一部分屬性

typedef struct sentinelRedisInstance {// 標識值,記錄了實例的類型,以及該實例的當前狀態int flags;// 實例的名字// 主服務器的名字由用戶在配置文件中設置// 從服務器以及 Sentinel 的名字由 Sentinel 自動設置// 格式為 ip:port ,例如 "127.0.0.1:26379"char *name;// 實例的運行 IDchar *runid;// 配置紀元,用于實現故障轉移uint64_t config_epoch;// 實例的地址sentinelAddr *addr;// SENTINEL down-after-milliseconds 選項設定的值// 實例無響應多少毫秒之后才會被判斷為主觀下線(subjectively down)mstime_t down_after_period;// SENTINEL monitor <master-name> <IP> <port> <quorum> 選項中的 quorum 參數// 判斷這個實例為客觀下線(objectively down)所需的支持投票數量int quorum;// SENTINEL parallel-syncs <master-name> <number> 選項的值// 在執行故障轉移操作時,可以同時對新的主服務器進行同步的從服務器數量int parallel_syncs;// SENTINEL failover-timeout <master-name> <ms> 選項的值// 刷新故障遷移狀態的最大時限mstime_t failover_timeout;// ...} sentinelRedisInstance;

創建連向主服務器的網絡連接。

?Sentinel 將成為主服務器的客戶端, 它可以向主服務器發送命令, 并從命令回復中獲取相關的信息。

對于每個被 Sentinel 監視的主服務器來說, Sentinel 會創建兩個連向主服務器的異步網絡連接:

  • 一個是命令連接, 這個連接專門用于向主服務器發送命令, 并接收命令回復。
  • 另一個是訂閱連接, 這個連接專門用于訂閱主服務器的?__sentinel__:hello?頻道。
為什么有兩個連接?在 Redis 目前的發布與訂閱功能中, 被發送的信息都不會保存在Redis 服務器里面, 如果在信息發送時, 想要接收信息的客戶 端不在線或者斷線, 那么這個客戶端就會丟失這條信息。因此, 為了不丟失 __sentinel__:hello 頻道的任何信息, Sentinel 必須專門用一個訂閱連接來接收該頻道的信息。而另一方面, 除了訂閱頻道之外, Sentinel 還又必須向主服務 器發送命令, 以此來與主服務器進行通訊, 所以 Sentinel 還 必須向主服務器創建命令連接。并且因為 Sentinel 需要與多個實例創建多個網絡連接, 所以Sentinel 使用的是異步連接。

接下來介紹 Sentinel 如何通過命令連接和訂閱連接與被監視主服務器進行通訊。

獲取服務器信息

sentinel默認每十秒鐘發送一次INFO命令給主服務器,并獲取信息:

1)關于主服務器本身的信息

2)主服務器屬下所有從服務器信息

sentinel發現主服務器有新的從服務器時,會創建相應的實例結構和命令連接,訂閱連接

給服務器發送消息

主觀下線

指的是單個Sentinel實例對服務器做出的下線判斷,即單個sentinel認為某個服務下線(有可能是接收不到訂閱,之間的網絡不通等等原因)。
如果服務器在down-after-milliseconds給定的毫秒數之內, 沒有返回 Sentinel 發送的 PING 命令的回復, 或者返回一個錯誤, 那么 Sentinel 將這個服務器標記為主觀下線(SDOWN )。
sentinel會以每秒一次的頻率向所有與其建立了命令連接的實例(master,從服務,其他sentinel)發ping命令,通過判斷ping回復是有效回復,還是無效回復來判斷實例時候在線(對該sentinel來說是“主觀在線”)。
sentinel配置文件中的down-after-milliseconds設置了判斷主觀下線的時間長度,如果實例在down-after-milliseconds毫秒內,返回的都是無效回復,那么sentinel回認為該實例已(主觀)下線,修改其flags狀態為SRI_S_DOWN。如果多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不同,這個在實際生產中要注意。

客觀下線


客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 實例在對同一個服務器做出 SDOWN 判斷, 并且通過 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服務器下線判斷,然后開啟failover。
客觀下線就是說只有在足夠數量的 Sentinel 都將一個服務器標記為主觀下線之后, 服務器才會被標記為客觀下線(ODOWN)。
只有當master被認定為客觀下線時,才會發生故障遷移。
當sentinel監視的某個服務主觀下線后,sentinel會詢問其它監視該服務的sentinel,看它們是否也認為該服務主觀下線,接收到足夠數量(這個值可以配置)的sentinel判斷為主觀下線,既任務該服務客觀下線,并對其做故障轉移操作。
sentinel通過發送 SENTINEL is-master-down-by-addr ip port current_epoch runid

(ip:主觀下線的服務id,port:主觀下線的服務端口,current_epoch:sentinel的紀元,runid:*表示檢測服務下線狀態,如果是sentinel 運行id,表示用來選舉領頭sentinel)

來詢問其它sentinel是否同意服務下線。
一個sentinel接收另一個sentinel發來的is-master-down-by-addr后,提取參數,根據ip和端口,檢測該服務時候在該sentinel主觀下線,并且回復is-master-down-by-addr,回復包含三個參數:down_state(1表示已下線,0表示未下線),leader_runid(領頭sentinal id),leader_epoch(領頭sentinel紀元)。
sentinel接收到回復后,根據配置設置的下線最小數量,達到這個值,既認為該服務客觀下線。
客觀下線條件只適用于主服務器: 對于任何其他類型的 Redis 實例, Sentinel 在將它們判斷為下線前不需要進行協商, 所以從服務器或者其他 Sentinel 永遠不會達到客觀下線條件。只要一個 Sentinel 發現某個主服務器進入了客觀下線狀態, 這個 Sentinel 就可能會被其他 Sentinel 推選出, 并對失效的主服務器執行自動故障遷移操作。

選舉大哥sentinel

一個redis服務被判斷為客觀下線時,多個監視該服務的sentinel協商,選舉一個領頭sentinel,對該redis服務進行故障轉移操作。選舉領頭sentinel遵循以下規則:
1)所有的sentinel都有公平被選舉成領頭的資格。
2)所有的sentinel都只有一次將某個sentinel選舉成領頭的機會(在一輪選舉中),一旦選舉,不能更改。
3)先到先得,一旦當前sentinel設置了領頭sentinel,以后要求設置sentinel為領頭請求都會被拒絕。
4)每個發現服務客觀下線的sentinel,都會要求其他sentinel將自己設置成領頭。
5)當一個sentinel(源sentinel)向另一個sentinel(目sentinel)發送is-master-down-by-addr ip port current_epoch runid命令的時候,runid參數不是*,而是sentinel運行id,就表示源sentinel要求目標sentinel選舉其為領頭。
6)源sentinel會檢查目標sentinel對其要求設置成領頭的回復,如果回復的leader_runid和leader_epoch為源sentinel,表示目標sentinel同意將源sentinel設置成領頭。
7)如果某個sentinel被半數以上的sentinel設置成領頭,那么該sentinel既為領頭。
8)如果在限定時間內,沒有選舉出領頭sentinel,暫定一段時間,再選舉。

為什么要選?
簡單來說,就是因為只能有一個sentinel節點去完成故障轉移。
sentinel is-master-down-by-addr這個命令有兩個作用,一是確認下線判定,二是進行領導者選舉。
過程:
1)每個做主觀下線的sentinel節點向其他sentinel節點發送上面那條命令,要求將它設置為領導者。
2)收到命令的sentinel節點如果還沒有同意過其他的sentinel發送的命令(還未投過票),那么就會同意,否則拒絕。
3)如果該sentinel節點發現自己的票數已經過半且達到了quorum的值,就會成為領導者
4)如果這個過程出現多個sentinel成為領導者,則會等待一段時間重新選舉。

轉移

1)挑一個新的主服務器

2)把其它從服務器的主服務器改成新的

3)把之前的主服務器改為新主服務器的從服務器

怎么挑新的主服務器

1)刪除所有下線服務器

2)刪除五秒內沒回復INOF命令的服務器

3)刪除數據舊的服務器(連接斷開超過down-after-millseconds*10)

4)根據優先級,選出最高的。

重點提煉

?

  • Sentinel 是一個特殊模式下的 Redis 服務器, 它使用了不同的命令表, 所以 Sentinel 能使用的命令和普通服務器不同。
  • Sentinel 會讀入用戶指定的配置文件, 為每個要被監視的主服務器創建相應的實例結構, 并創建連向主服務器的命令連接和訂閱連接, 其中命令連接用于向主服務器發送命令請求, 而訂閱連接則用于接收指定頻道的消息。
  • Sentinel 向主服務器發送?INFO?命令獲得屬下從服務器信息, 為這些從服務器創建實例結構、命令連接和訂閱連接。
  • 默認 Sentinel 十秒一次向被監視的主服務器和從服務器發送?INFO?命令, 當主服務器處于下線狀態, 或者 Sentinel 正在對主服務器進行故障轉移操作時, Sentinel 向從服務器發送?INFO?命令的頻率會改為每秒一次。
  • 對于監視同一個主服務器和從服務器的多個 Sentinel 來說, 它們會以每兩秒一次的頻率, 通過向被監視服務器的?__sentinel__:hello?頻道發送消息來向其他 Sentinel 宣告自己的存在。
  • 每個 Sentinel 也會從?__sentinel__:hello?頻道中接收其他 Sentinel 發來的信息, 并根據這些信息為其他 Sentinel 創建相應的實例結構, 以及命令連接。
  • Sentinel 只會與主服務器和從服務器創建命令連接和訂閱連接, Sentinel 與 Sentinel 之間則只創建命令連接。
  • Sentinel 以每秒一次的頻率向實例(包括主服務器、從服務器、其他 Sentinel)發送?PING?命令, 并根據實例對?PING?命令的回復來判斷實例是否在線
  • 當 Sentinel 將一個主服務器判斷為主觀下線時, 它會向同樣監視這個主服務器的其他 Sentinel 進行詢問, 看它們是否同意這個主服務器已經進入主觀下線狀態。
  • 當 Sentinel 收集到足夠多的主觀下線投票之后, 它會將主服務器判斷為客觀下線, 并發起一次針對主服務器的故障轉移操作。

總結

以上是生活随笔為你收集整理的redis——sentinel的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。