Redis總結(十)redis集群-哨兵模式

模式二:哨兵模式

上一篇問講述了redis集群的主從模式溶褪,這一篇我們講述哨兵模式志衍。

Redis 的 Sentinel 系統(tǒng)用于管理多個 Redis 服務器(instance)悲没, 該系統(tǒng)執(zhí)行以下三個任務:

  • 監(jiān)控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
  • 提醒(Notification): 當被監(jiān)控的某個 Redis 服務器出現(xiàn)問題時第煮, Sentinel 可以通過 API 向管理員或者其他應用程序發(fā)送通知撩炊。
  • 自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時结耀, Sentinel 會開始一次自動故障遷移操作留夜, 它會將失效主服務器的其中一個從服務器升級為新的主服務器匙铡, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時碍粥, 集群也會向客戶端返回新主服務器的地址鳖眼, 使得集群可以使用新主服務器代替失效服務器。

這個就相比于主從系統(tǒng)更加的靈活化嚼摩,主從系統(tǒng)一旦主節(jié)點崩潰钦讳,整個系統(tǒng)寫的功能就喪失。

Redis Sentinel 是一個分布式系統(tǒng)枕面, 你可以在一個架構中運行多個 Sentinel 進程(progress)愿卒, 這些進程使用流言協(xié)議(gossip protocols)來接收關于主服務器是否下線的信息, 并使用投票協(xié)議(agreement protocols)來決定是否執(zhí)行自動故障遷移潮秘, 以及選擇哪個從服務器作為新的主服務器琼开。

哨兵進程工作方式:

  1. 每個Sentinel(哨兵)進程以每秒鐘一次的頻率向整個集群中的Master主服務器,Slave從服務器以及其他Sentinel(哨兵)進程發(fā)送一個 PING 命令枕荞。
  2. 如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值柜候, 那么這個實例會被 Sentinel 標記為主觀下線。 一個有效回復可以是: +PONG 躏精、 -LOADING 或者 -MASTERDOWN 渣刷。
  3. 如果一個主服務器被標記為主觀下線, 那么正在監(jiān)視這個主服務器的所有 Sentinel 要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態(tài)矗烛。
  4. 如果一個主服務器被標記為主觀下線辅柴, 并且有足夠數(shù)量的 Sentinel (至少要達到配置文件指定的數(shù)量)在指定的時間范圍內(nèi)同意這一判斷, 那么這個主服務器被標記為客觀下線高诺。
  5. 在一般情況下碌识, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有主服務器和從服務器發(fā)送 INFO 命令碾篡。 當一個主服務器被 Sentinel 標記為客觀下線時虱而, Sentinel 向下線主服務器的所有從服務器發(fā)送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
  6. 只要一個 Sentinel 發(fā)現(xiàn)某個主服務器進入了客觀下線狀態(tài)开泽, 這個 Sentinel 就可能會被其他 Sentinel 推選出牡拇, 并對失效的主服務器執(zhí)行自動故障遷移操作。
  7. 當沒有足夠數(shù)量的 Sentinel 同意主服務器已經(jīng)下線穆律, 主服務器的客觀下線狀態(tài)就會被移除惠呼。 當主服務器重新向 Sentinel 的 PING 命令返回有效回復時, 主服務器的主觀下線狀態(tài)就會被移除峦耘。

主觀下線以及客觀下線解釋

主觀下線(Subjectively Down剔蹋, 簡稱 SDOWN)指的是單個 Sentinel 實例對服務器做出的下線判斷。

客觀下線(Objectively Down辅髓, 簡稱 ODOWN)指的是多個 Sentinel 實例在對同一個服務器做出 SDOWN 判斷泣崩, 并且通過 SENTINEL is-master-down-by-addr 命令互相交流之后少梁, 得出的服務器下線判斷。

從主觀下線狀態(tài)切換到客觀下線狀態(tài)并沒有使用嚴格的法定人數(shù)算法(strong quorum algorithm)矫付, 而是使用了流言協(xié)議: 如果 Sentinel 在給定的時間范圍內(nèi)凯沪, 從其他 Sentinel 那里接收到了足夠數(shù)量的主服務器下線報告, 那么 Sentinel 就會將主服務器的狀態(tài)從主觀下線改變?yōu)榭陀^下線买优。 如果之后其他 Sentinel 不再報告主服務器已下線妨马, 那么客觀下線狀態(tài)就會被移除。

客觀下線條件只適用于主服務器: 對于任何其他類型的 Redis 實例杀赢, Sentinel 在將它們判斷為下線前不需要進行協(xié)商烘跺, 所以從服務器或者其他 Sentinel 永遠不會達到客觀下線條件。

Sentinel是如何發(fā)現(xiàn)其他的Sentinel 和從服務器的脂崔?

  1. 每個 Sentinel 會以每兩秒一次的頻率液荸, 通過發(fā)布與訂閱功能, 向被它監(jiān)視的所有主服務器和從服務器的 sentinel:hello 頻道發(fā)送一條信息脱篙, 信息中包含了 Sentinel 的 IP 地址娇钱、端口號和運行 ID (runid)。
  2. 每個 Sentinel 都訂閱了被它監(jiān)視的所有主服務器和從服務器的 sentinel:hello 頻道绊困, 查找之前未出現(xiàn)過的 sentinel (looking for unknown sentinels)文搂。 當一個 Sentinel 發(fā)現(xiàn)一個新的 Sentinel 時, 它會將新的 Sentinel 添加到一個列表中秤朗, 這個列表保存了 Sentinel 已知的煤蹭, 監(jiān)視同一個主服務器的所有其他 Sentinel 。
  3. Sentinel 發(fā)送的信息中還包括完整的主服務器當前配置(configuration)取视。 如果一個 Sentinel 包含的主服務器配置比另一個 Sentinel 發(fā)送的配置要舊硝皂, 那么這個 Sentinel 會立即升級到新配置上。
  4. 在將一個新 Sentinel 添加到監(jiān)視主服務器的列表上面之前作谭, Sentinel 會先檢查列表中是否已經(jīng)包含了和要添加的 Sentinel 擁有相同運行 ID 或者相同地址(包括 IP 地址和端口號)的 Sentinel 稽物, 如果是的話, Sentinel 會先移除列表中已有的那些擁有相同運行 ID 或者相同地址的 Sentinel 折欠, 然后再添加新 Sentinel 贝或。

從上述我們可以看出哨兵之間的互相發(fā)現(xiàn)以及發(fā)現(xiàn)從服務器,都是通過發(fā)布訂閱的功能來實現(xiàn)的锐秦,既我們之前所講的redis的發(fā)布訂閱咪奖。當有一個新的哨兵加入進來就會向頻道中發(fā)送自己的信息,其他所有訂閱的哨兵會通過消費信息添加新的哨兵信息酱床。

自動故障遷移過程:

  • 發(fā)現(xiàn)主服務器已經(jīng)進入客觀下線狀態(tài)羊赵。
  • 在失效主服務器屬下的從服務器當中, 那些被標記為主觀下線扇谣、已斷線昧捷、或者最后一次回復 PING 命令的時間大于五秒鐘的從服務器都會被淘汰揖闸。
  • 在失效主服務器屬下的從服務器當中, 那些與失效主服務器連接斷開的時長超過 down-after 選項指定的時長十倍的從服務器都會被淘汰料身。
  • 在經(jīng)歷了以上兩輪淘汰之后剩下來的從服務器中汤纸, 我們選出復制偏移量(replication offset)最大的那個從服務器作為新的主服務器; 如果復制偏移量不可用芹血, 或者從服務器的復制偏移量相同贮泞, 那么帶有最小運行 ID 的那個從服務器成為新的主服務器。
  • 向被選中的從服務器發(fā)送 SLAVEOF NO ONE 命令幔烛,讓它轉(zhuǎn)變?yōu)橹鞣掌鳌?/li>
  • 通過發(fā)布與訂閱功能啃擦, 將更新后的配置傳播給所有其他 Sentinel , 其他 Sentinel 對它們自己的配置進行更新饿悬。
  • 向已下線主服務器的從服務器發(fā)送 SLAVEOF 命令令蛉, 讓它們?nèi)椭菩碌闹鞣掌鳌?/li>
  • 當所有從服務器都已經(jīng)開始復制新的主服務器時, 領頭 Sentinel 終止這次故障遷移操作狡恬。

上述簡單講述了:

  • Sentinel是如何發(fā)現(xiàn)其他的Sentinel 以及從服務器
  • Sentinel是如何判斷主服務器主觀下線以及客觀下線的
  • Sentinel是如何自動故障遷移的

下面我們將具體的搭建哨兵模式

首先我們像搭建主從模式一樣珠叔,搭建出主從并啟動,如上一篇文章一樣弟劲,這里我們主節(jié)點為:6380端口祷安,從節(jié)點為6381端口,如圖所示:

redis包.png
哨兵模式主從節(jié)點.png

啟動主從后兔乞,6380redis文件中創(chuàng)建哨兵模式所需要的配置文件汇鞭,需要啟動幾個哨兵就創(chuàng)建幾個配置文件,如圖:

哨兵模式配置文件.png

配置文件內(nèi)容如下:

哨兵配置1.png
哨兵2配置.png

如上就是我們需要的全部配置,現(xiàn)在我們開始啟動兩個哨兵庸追。

啟動命令為 redis-service sentinel.conf --sentinel

首先啟動端口號為26379的哨兵霍骄,如圖:

哨兵1啟動.png

啟動端口號為26380的哨兵,如圖:

哨兵2啟動.png

此時我們查看主節(jié)點服務的模式也是哨兵模式淡溯。

主節(jié)點信息.png

并且我們可以看到兩個哨兵啟動成功后读整,兩個哨兵的配置文件也有所變化:

哨兵1配置改變.png

可以看到兩個配置文件都自動添加了從節(jié)點以及另一個哨兵的信息。

此時我們的redis哨兵模式就創(chuàng)建成功了血筑,后面我們測試主節(jié)點斷開及主節(jié)點恢復的時候和java代碼結合演示绘沉。

我們要整合哨兵模式,首先要修改redis的配置文件豺总。如下:

@Component
@Slf4j
public class JedisConfig {
    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.pool.max-wait}")
    private long maxWaitMillis;

    @Bean
    public JedisSentinelPool redisPoolFactory(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMinIdle(minIdle);
        //此處配置的哨兵信息,切記不要配置主節(jié)點地址择懂,這樣故障遷移的時候才能切換過來喻喳。
        Set<String> sentinels = new HashSet<String>(Arrays.asList("127.0.0.1:26379","127.0.0.1:26380"));
//      JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,null);
        JedisSentinelPool jedisPool = new JedisSentinelPool("mymaster",sentinels,jedisPoolConfig);
        log.info("JedisPool注入成功!");
        log.info("redis地址:" + host + ":" + port);
        return  jedisPool;
    }

}

并將RedisClient中連接池修改:

    //@Resource
    //private JedisPool jedisPool;

    @Resource
    private JedisSentinelPool jedisPool;
    
    這個具體配置之前文章中有詳細內(nèi)容

我們先測試一下哨兵模式是否連接正常

    @Test
    public   void setRedis()  {
        try {
            redisClient.set("testSentinel5","aaaa");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

運行結果:

測試結果.png

可以看到連接正常困曙,那么我們現(xiàn)在將主節(jié)點關掉表伦,測試一下故障遷移谦去。

主節(jié)點斷開后情況.png

從上圖我們可以看出在6380主節(jié)點斷開后,6381從節(jié)點講過哨兵的故障遷移變?yōu)榱酥鞴?jié)點蹦哼。

并且我們可以看到原先加在6381從節(jié)點redis.windows.conf配置文件中的slaveof配置以及自動刪除了鳄哭,而且兩個哨兵中的主節(jié)點監(jiān)控也由6380變?yōu)榱?381.

斷開主節(jié)點后哨兵配置.png

我們再測試一下遷移后的寫入功能。

  @Test
    public   void setRedis()  {
        try {
            redisClient.set("testSentinel6","aaaa");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
故障遷移后寫入.png

可以看出在主節(jié)點斷開后纲熏,集群的寫入查看功能正常妆丘。

接下來我們將6380恢復,看是否能夠重新連接入集群:

6380恢復后.png

可以看到6380重新開啟后局劲,自動變?yōu)閺墓?jié)點連接入集群勺拣,并在6380的redis.windows.conf的配置文件中自動加入了:

slaveof 10.66.205.85 6381

今天就寫到這里了,Redis的哨兵模式是以主從模式為基礎的鱼填,所以說药有,主從模式擁有的一些缺點,在哨兵模式下也具有苹丸。哨兵模式主要是監(jiān)控Master主服務器的運行情況愤惰,當然也會監(jiān)控Slave從服務器的運行情況,如果Master主服務器發(fā)生了故障赘理,該模式可以保證Slave從服務器順利升級為Master主服務器繼續(xù)提供服務羊苟,以此提高系統(tǒng)的高可用性。雖然哨兵模式比主從模式提高了不少系統(tǒng)的高可用性感憾,但是該模式不能水平擴容蜡励,不能動態(tài)的增、刪節(jié)點阻桅,這也是限制哨兵模式廣泛應用的主要原因凉倚。Redis也看到了這個情況,所在在Redis的3.x以后的版本提供了一個更加強大集群模式嫂沉,那就是Cluster集群模式稽寒,這個模式也是我們下一篇文章的主題。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趟章,一起剝皮案震驚了整個濱河市杏糙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚓土,老刑警劉巖宏侍,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜀漆,居然都是意外死亡谅河,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绷耍,“玉大人吐限,你說我怎么就攤上這事」邮迹” “怎么了诸典?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長崎苗。 經(jīng)常有香客問我狐粱,道長,這世上最難降的妖魔是什么益缠? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任脑奠,我火速辦了婚禮,結果婚禮上幅慌,老公的妹妹穿的比我還像新娘宋欺。我一直安慰自己,他們只是感情好胰伍,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布齿诞。 她就那樣靜靜地躺著,像睡著了一般骂租。 火紅的嫁衣襯著肌膚如雪祷杈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天渗饮,我揣著相機與錄音但汞,去河邊找鬼。 笑死互站,一個胖子當著我的面吹牛私蕾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胡桃,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼踩叭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了翠胰?” 一聲冷哼從身側響起容贝,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎之景,沒想到半個月后斤富,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡闺兢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年茂缚,在試婚紗的時候發(fā)現(xiàn)自己被綠了戏罢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屋谭。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡脚囊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桐磁,到底是詐尸還是另有隱情悔耘,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布我擂,位于F島的核電站衬以,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏校摩。R本人自食惡果不足惜看峻,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望衙吩。 院中可真熱鬧互妓,春花似錦、人聲如沸坤塞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摹芙。三九已至灼狰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浮禾,已是汗流浹背交胚。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盈电,地道東北人蝴簇。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像挣轨,于是被迫代替她去往敵國和親军熏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361