Redis哨兵機制

 

若是master異常,則會進行master-slave切換,將其中一個slave做爲master,將以前的master做爲slave。redis

哨兵做用

哨兵是Redis集羣架構中很是重要的一個組件,主要功能以下:服務器

  • 集羣監控:負責監控redis master和slave進程是否正常網絡

  • 消息通知:若是某個redis實例有故障,那麼哨兵負責發送消息做爲報警通知給管理員架構

  • 故障轉移:若是master節點掛掉了,會自動轉移到slave節點上分佈式

  • 配置中心:若是故障轉移發生了,通知client客戶端新的master地址ide

哨兵的核心知識
  • 故障轉移時,判斷一個master節點是否宕機了,須要大部分的哨兵都贊成才行,涉及到了分佈式選舉的問題測試

  • 哨兵至少須要3個實例,來保證本身的健壯性ui

  • 哨兵+redis主從的部署架構,是不會保證數據零丟失的,只能保證redis集羣的高可用性server

sdown和odown
  • sdown和odown兩種失敗的狀態blog

  • sdown是主觀宕機,就一個哨兵若是本身以爲一個master宕機了,那麼就是主觀宕機

  • odown是客觀宕機,若是quorum數量的哨兵都以爲一個master宕機了,那麼就是客觀宕機

  • sdown達成的條件:若是一個哨兵ping一個master,超過了is-master-down-after-milliseconds指定的毫秒數以後,就認爲master宕機

  • odown達成條件:若是一個哨兵在指定的時間內,收到了quorum指定數量的其餘哨兵也認爲那個master是宕機了,那麼就認爲是odown了,客觀認爲master宕機了

quorum和majority
  1. quorum:確認odown的最少哨兵數量

  2. majority:受權進行主從切換的最少哨兵數量

  3. 每個哨兵要作主備切換,首先須要quorum數量的哨兵認爲odown,而後選舉出一個哨兵來作切換,這個哨兵還得獲得majority哨兵的特權,才能進行切換。

  4. 若是quorum<majority,好比5個哨兵,majority就是3,quorum·設置爲2,那麼3個哨兵受權能夠執行切換,可是若是quorum>majority,那麼必須quorum數量的哨兵都受權,好比5個哨兵,quorum是5,那麼必須5個哨兵都贊成受權才能執行。(誰多聽誰的)

爲何哨兵至少3個節點?

哨兵集羣必須部署兩個以上節點。若是哨兵集羣僅僅部署了2個哨兵實例,那麼它的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),若是其中一個哨兵宕機了,就沒法知足majority>=2這個條件,那麼master發生故障時也就沒法進行主從切換了。

  工做原理

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

  1. 每一個Sentienl以每秒鐘一次的頻率向他所知的Master,Slave以及其餘的Sentinel實例發送一個ping命令

  2. 若是一個實例距離最後一次有效回覆ping命令的時間超過了down-after-milliseconds選項所指的值,則這個實例會被Sentinel標記爲主觀宕機

  3. 若是一個master被標記爲主觀宕機,則正在監視這個master的全部sentinel要以每一秒一次的頻率確認Master的確進入了主觀宕機狀態

  4. 當有足夠數量的Sentinel(大於等於配置文件所指的值)在指定的時間範圍內確認master的確進入了主觀宕機狀態,則master會被標記爲客觀狀態

  5. 在通常狀況下,每一個Sentinel會以1次/10秒的頻率向他一致的全部master,slave發送INFO命令

  6. 當master被Sentinel標記爲客觀宕機是,Sentinel向下線的master的全部slave發送INFO命令的頻率會從1次/10秒改成1次/秒

  7. 若沒有足夠數量的Sentinel贊成master已經下線,master的客觀宕機狀態就會被移除;若master從新想Sentinel的ping命令返回有效回覆,master的主觀宕機狀態就會被移除。

哨兵模式的配置

首先配置redis的主從服務器,修改redis.conf文件以下

# 使得Redis服務器能夠跨網絡訪問
bind 0.0.0.0
# 設置密碼
requirepass "123456"
# 指定主服務器,注意:有關slaveof的配置只是配置從服務器,主服務器不須要配置
slaveof 192.168.11.128 6379
# 主服務器密碼,注意:有關slaveof的配置只是配置從服務器,主服務器不須要配置
masterauth 123456

上述內容主要是配置Redis服務器,從服務器比主服務器多了一個slaveof的配置和密碼

配置3個哨兵,每一個哨兵都是同樣的。在Redis安裝目錄下有一個sentinel.conf文件,copy一份進行修改

# 禁止保護模式
protected-mode no
# 配置監聽的主服務器,這裏sentinel monitor表明監控,mymaster表明服務器的名稱,能夠自定義,192.168.11.128表明監控的主服務器,6379表明端口,2表明只有兩個或兩個以上的哨兵認爲主服務器不可用的時候,纔會進行failover操做。
sentinel monitor mymaster 192.168.11.128 6379 2
# sentinel author-pass定義服務的密碼,mymaster是服務名稱,123456是Redis服務器密碼
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456

啓動服務器和哨兵,進入Redis安裝目錄的src目錄

# 啓動Redis服務器進程
./redis-server ../redis.conf
# 啓動哨兵進程
./redis-sentinel ../sentinel.conf
注意啓動順序:首先是主機(192.168.11.128)的Redis服務進程,而後啓動叢機的服務進程,最後啓動3個哨兵的服務進程Java中使用哨兵模式
/** * 測試Redis哨兵模式 * @author liu */public class TestSentinels {    @SuppressWarnings("resource")    @Test    public void testSentinel() {        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();        jedisPoolConfig.setMaxTotal(10);        jedisPoolConfig.setMaxIdle(5);        jedisPoolConfig.setMinIdle(5);        // 哨兵信息        Set<String> sentinels = new HashSet<>(Arrays.asList("192.168.11.128:26379",                "192.168.11.129:26379","192.168.11.130:26379"));        // 建立鏈接池        JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig,"123456");        // 獲取客戶端        Jedis jedis = pool.getResource();        // 執行兩個命令        jedis.set("mykey", "myvalue");        String value = jedis.get("mykey");        System.out.println(value);    }}
相關文章
相關標籤/搜索