欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解redis高可用Sentinel?

 更新時間:2024年05月06日 08:33:37   作者:小生凡一  
本文主要介紹了redis高可用Sentinel的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

寫在前面

redis 在我們日常的業(yè)務開發(fā)中是十分常見的,而redis的可用性就必須要有很高的要求,那么 redis集群的高可用由有一個或者多個 Sentinel(哨兵) 實例組成的 哨兵系統(tǒng)來保證的。

哨兵

由一個或者多個 Sentinel 實例組成的 Sentinel 系統(tǒng)可以監(jiān)控任意多個主服務器,以及這些主服務器屬下的所有從服務器,并在被監(jiān)視的主服務器進入下線狀態(tài)時,自動將下線主服務器屬下的某個從服務器升級為新主服務器,然后有新的主服務器代替已下線的主服務器繼續(xù)處理命令請求。

在這里插入圖片描述

簡介

Sentinel 本質上只是一個運行在特殊模式下的Redis服務器,但是 Sentinel 和 Redis的初始化和工作內容是不同的。Sentinel 不需要使用數(shù)據(jù)庫,所以初始化的時候是不需要載入RDB文件或者AOF文件的。而Sentinel的工作內容如下:

功能使用情況
數(shù)據(jù)庫鍵值對命令 SET、DEL、FLUSHDB不使用
事務命令 MULTI,WATCH不使用
腳本命令 EVAL不使用
RDB/AOF持久化命令 SAVE、BGSAVE、BGREWRITEAOF不使用
復制命令,SLAVEOFSentinel 內部使用,但是客戶端不用
發(fā)布與訂閱命令,比如 PUBLISH 和 SUBSCRIBESUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUBSUBSCRIBE這四個命令在Sentinel內部和客戶端都可以使用,但PUBLISH命令只能在Sentinel內部使用
文件事件處理器(負責發(fā)送命令和請求、處理命令回復)Sentinel 內部使用,但關聯(lián)的文件事件處理器和普通Redis處理器不同
事件處理器(負責執(zhí)行serverCron 函數(shù))Sentinel 內部使用,時間事件的處理器仍然是ServerCron函數(shù),ServerCron函數(shù)會調用sentinel.c/sentineTimer函數(shù),后者包含了Sentinel要執(zhí)行的所有操作

在為什么啟動Sentinel的時候,會有這些限制呢?Sentinel 不都是 Redis 嗎?

因為在Sentinel初始化的時候,加載的是 src/sentinel.c 文件的函數(shù),而Redis加載的是 src/redis.c 文件的函數(shù),而這兩個文件的初始化函數(shù),限定了只能使用哪些命令

數(shù)據(jù)結構

Sentinel 的結構體如下

typedef struct sentinelRedisInstance {
    int flags;      // 標識,記錄實例類型
    char *name;     // 該實例名字
    char *runid;    // 實例的運行id
    uint64_t config_epoch;  // 配置紀元,用于實現(xiàn)故障轉移
    sentinelAddr *addr; 	// 實例地址
    mstime_t last_pub_time;   // 上次我們通過 Pub/Sub 發(fā)送了 hello 的時間。 
    mstime_t last_hello_time; // 僅在設置 SRI_SENTINEL 時使用。上次我們發(fā)送hello的響應時間
    mstime_t last_master_down_reply_time; // SENTINEL is-master-down command.命令的最新響應時間
	// ... 
    mstime_t down_after_period; // 實例無響應多少毫秒之后才會被判斷為主觀下線
	// ...
    // Master 配置
    unsigned int quorum;// 判斷這個實例為客觀下線鎖需要支持的投票數(shù)量
	// ... 
    // Slave 配置
	int slave_priority; /* Slave 優(yōu)先級 */
    struct sentinelRedisInstance *master; /* Master instance if it's slave. */
    char *slave_master_host;    /* Master host as reported by INFO */
    int slave_master_port;      /* Master port as reported by INFO */
    int slave_master_link_status; /* Master link status as reported by INFO */
    unsigned long long slave_repl_offset; /* Slave 復制的偏移量. */
    // ...
} sentinelRedisInstance;

創(chuàng)建鏈接

初始化Sentinel的最后一步是創(chuàng)建連向被監(jiān)控主服務器的網絡連接,Sentinel 將成為主服務器的客戶端,可以向主服務器發(fā)送命令,并且從命令回復中獲取相關的信息。

對于每個被Sentinel 監(jiān)視的主服務器來說,Sentinel會創(chuàng)建兩個連接主服務器的異步網絡連接:

  • 命令連接,這個連接專門用于向主服務器發(fā)送命令,并接受命令回復。
  • 訂閱連接,這個連接專門用于訂閱主服務器的 __sentinel__:hello 頻道。

為什么會有兩個連接?
在Redis目前的發(fā)布與訂閱功能中,被i發(fā)送的信息都不會保存在Redis服務器里面,如果在信息發(fā)送時,想要接受信息的客戶端不在線或者斷線,那么這個客戶端就會丟失這條信息。 因此為了不丟失__sentinel__:hello 頻道的任何信息,Sentinel必須專門用一個連接來接受該頻道的信息。除了訂閱頻道之外,Sentinel還必須向主服務器發(fā)送命令,以此來與主服務器進行通信,所以Sentinel還必須向主服務器創(chuàng)建命令連接。

在這里插入圖片描述

獲取信息 INFO

Sentinel 默認會以每十秒一次的頻率,通過命令連接向被監(jiān)視的主服務器發(fā)送 INFO命令 ,并通過分析 INFO 命令的回復 來獲取主服務器的當前信息。

一般INFO命令的回復有以下信息:

  • 從服務器的運行ID、角色role、優(yōu)先級slave_priority、復制偏移量
  • 主服務器的IP地址 master_host 以及主服務器的端口號 master_port
  • 主從服務器的連接狀態(tài)master_link_status

獲取到這些信息之后,就會更新存儲到Sentinel的結構體中。

在這里插入圖片描述

但是當主服務器處于下線狀態(tài),或者Sentinel正在對主服務器和從服務器進行故障轉移操作時,Sentinel 向從服務器發(fā)送INFO命令的頻率將會變成每秒一次。

發(fā)送命令

對于監(jiān)視同一個主服務器和從服務器的多個Sentinel來說,他們會以每兩秒一次的頻率,通過被監(jiān)視服務器的 __sentinel:hello__ 頻道發(fā)送消息來響應其他sentinel宣告自己的存在。

PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

這條命令向服務器的__sentinel__:hello頻道發(fā)送一條信息,這些信息的組成如下:

  • s_ 開頭的是sentinel本身的信息。
  • m_開頭的是主服務器的信息。如果此sentinel監(jiān)視的是主服務器,那么這個參數(shù)就是主服務器的參數(shù),如果監(jiān)視的是從服務器,那么就是這個從服務器正在所復制的主服務器。

接收命令

當sentinel與一個主服務器或者從服務器建立起訂閱連接之后,sentinel就會就會通過訂閱連接,向服務器發(fā)送以下命令:

SUBSCRIBE __sentinel__:hello

也就是說對于每一個sentinel連接的服務器,sentinel既通過命令連接到服務器的__sentinel__:hello 頻道發(fā)送信息,又通過訂閱連接服務器的__sentinel__:hello頻道接受消息。

在這里插入圖片描述

那么對于監(jiān)視同一個服務器的多個sentinel來說,一個sentinel發(fā)送的信息就會被其他sentinel接受到,因為是監(jiān)聽訂閱了同一個服務器的__sentinel__:hello頻道,所sentinel就會感知到其他sentinel的存在。并sentinel將會更新其他的sentinel信息到自己的sentinel字典中。

在這里插入圖片描述

sentinel 之間的通信

從上面我們知道每個Sentinel也會從__sentinel:hello__ 頻道中接收其他Sentinel發(fā)送來的信息,并根據(jù)這些信息為其他Sentinel創(chuàng)建實例結構和命令連接。

在這里插入圖片描述

但是Sentinel 只會與主服務器和從服務器創(chuàng)建命令連接和訂閱連接,Sentinel 和 Sentinel 之間則只創(chuàng)建命令連接。

為什么sentinel與sentinel之間不需要創(chuàng)建訂閱連接呢?
首先我們要確定訂閱連接是用來干嘛的,訂閱連接是用來發(fā)現(xiàn)其他節(jié)點的,而sentinel已經通過主服務器或者從服務器的頻道信息來發(fā)現(xiàn)未知的sentinel,也就是說sentinel訂閱了主/從服務器已經知道了其他的sentinel,就不需要再進行訂閱連接其他的sentinel了,而相互已知的sentinel只需要使用命令連接來進行通信就夠了。

主/客觀下線

Sentinel 會以每秒一次的頻率向實例,包括主服務器,從服務器,其他Sentinel發(fā)送 PING 命令,并根據(jù)實例對PING命令的回復判斷實例是否在線,當一個實例在指定的時長中連續(xù)向Sentinel發(fā)送無效回復時,Sentinel就會判斷為主觀下線。

在這里插入圖片描述

Sentinel1 將向 Sentinel2、server、slave1、slave2發(fā)送ping命令。sentinel2也會進行同樣的操作。那么一般會得到以下兩種情況的回復

  • 有效回復:返回 PONG、LOADING、MASTERDOWN 三個中的一個
  • 無效回復:非有效回復的內容,或者是指定時間內沒有返回任何的回復,而這個指定時間的字段為down-after-milliseconds。

當Sentinel講一個主服務器判斷為主觀下線,他會向同樣監(jiān)視這個主服務器的其他 Sentinel 進行詢問,如果有足夠多的結點判定這個主服務器為主觀下線,那么就狀態(tài)改成客觀下線,某個節(jié)點的狀態(tài)改成客觀下線之后,監(jiān)視這個節(jié)點的各個sentinel就會協(xié)商選取一個leader sentinel節(jié)點,并且由領頭的 leader sentinel 節(jié)點發(fā)起一次針對主服務器的故障轉移。

這個選舉的過程在這里就不過多介紹了。有點類似raft。后面有空再說明。

故障轉移

在選舉出leader sentinel節(jié)點之后的故障轉移會做以下幾件事情:

  • 在已下線主服務器屬下的所有從服務器里面,挑選出一個從服務器,并將其轉化成主服務器。
  • 讓已下線的主服務器屬下的所有從服務器改成復制新的主服務器。
  • 將已下線主服務器設置為新的從服務器

新的主服務器是如何挑選出來的呢?首先leader sentinel節(jié)點會將已下線主服務器的所有從服務器保存到一個列表,根據(jù)一些規(guī)則進行過濾:

  • 刪除已下線或者狀態(tài)不正常的從服務器,保證列表中剩余的從服務器是正常的。
  • 刪除所有最近5秒內沒有回復leader sentinel節(jié)點的INFO命令的從服務器,保證列表中的從服務器都是最新通信成功的。
  • 刪除與已下線的主服務器連接斷開超過 down-after-milliseconds * 10 毫秒的從服務器,保證剩余的服務器保存的數(shù)據(jù)都是比較新

down-after-milliseconds:實例失去聯(lián)系的時間,而刪除斷開這個時間的10倍,是為了能保證剩余的從服務器沒有過早的與主服務器斷開連接。

  • 會根據(jù)從服務器的優(yōu)先級進行排序,選擇最高優(yōu)先級的從服務器,如果相同優(yōu)先級,則選擇偏移量最大服務器。因為偏移量大意味著數(shù)據(jù)最新。

易主

選擇完主服務器之后,就開始改變從服務器的復制對象了。這一動作可以通過向服務器發(fā)送SLAVEOF的命令來實現(xiàn)。

在這里插入圖片描述

本文我們詳細介紹了redis集群中sentinel的數(shù)據(jù)結構,sentinel與主從服務器的連接,信息傳遞,以及主從服務器發(fā)生故障時的處理方式。

那么問題來了?如果sentinel 集群中某一個sentinel節(jié)點掛了會發(fā)送什么事情呢?

到此這篇關于redis 高可用 Sentinel 詳解的文章就介紹到這了,更多相關redis 高可用 Sentinel內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • redis使用Lua腳本解決多線程下的超賣問題及原因解析

    redis使用Lua腳本解決多線程下的超賣問題及原因解析

    這篇文章主要介紹了redis使用Lua腳本解決多線程下的超賣問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • 從零搭建SpringBoot2.X整合Redis框架的詳細教程

    從零搭建SpringBoot2.X整合Redis框架的詳細教程

    這篇文章主要介紹了從零搭建SpringBoot2.X整合Redis框架的詳細教程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Linux中設置Redis開機啟動的方法

    Linux中設置Redis開機啟動的方法

    這篇文章主要給大家介紹了關于Linux中設置Redis開機啟動的方法,主要包括在CentOS7.0系統(tǒng)和Debian 8.0系統(tǒng)下實現(xiàn)方法,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • 編譯安裝redisd的方法示例詳解

    編譯安裝redisd的方法示例詳解

    這篇文章主要介紹了編譯安裝redisd的方法示例詳解,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • Redis IP地址的綁定的實現(xiàn)

    Redis IP地址的綁定的實現(xiàn)

    這篇文章主要介紹了Redis IP地址的綁定的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • Redis高并發(fā)問題的解決方法

    Redis高并發(fā)問題的解決方法

    這篇文章主要介紹了Redis高并發(fā)問題的解決辦法,具有很好的參考價值,感興趣的小伙伴們可以參考一下,具體如下:
    2018-05-05
  • 在項目中使用redis做緩存的一些思路

    在項目中使用redis做緩存的一些思路

    這篇文章主要介紹了在項目中使用redis做緩存的一些思路,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Redis:Redisson分布式鎖的使用方式(推薦使用)

    Redis:Redisson分布式鎖的使用方式(推薦使用)

    這篇文章主要介紹了Redis:Redisson分布式鎖的使用方式(推薦使用),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Redis 內存碎片原因及清理

    Redis 內存碎片原因及清理

    內存碎片是指在內存分配的時候,產生的不能重復利用的空間,本文主要介紹了Redis 內存碎片原因及清理,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • SpringBoot整合Redis實現(xiàn)序列化存儲Java對象的操作方法

    SpringBoot整合Redis實現(xiàn)序列化存儲Java對象的操作方法

    這篇文章主要介紹了SpringBoot整合Redis實現(xiàn)序列化存儲Java對象,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03

最新評論