Redis哨兵(Sentinel)模式

主從切換技術(shù)的方法是:當(dāng)主服務(wù)器宕機(jī)后锋玲,需要手動(dòng)把一臺(tái)從服務(wù)器切換為主服務(wù)器灭返,這就需要人工干預(yù)盗迟,費(fèi)事費(fèi)力,還會(huì)造成一段時(shí)間內(nèi)服務(wù)不可用熙含。這不是一種推薦的方式罚缕,更多時(shí)候,我們優(yōu)先考慮哨兵模式怎静。

一邮弹、哨兵模式概述

哨兵模式是一種特殊的模式,首先Redis提供了哨兵的命令蚓聘,哨兵是一個(gè)獨(dú)立的進(jìn)程腌乡,作為進(jìn)程,它會(huì)獨(dú)立運(yùn)行夜牡。其原理是哨兵通過(guò)發(fā)送命令导饲,等待Redis服務(wù)器響應(yīng),從而監(jiān)控運(yùn)行的多個(gè)Redis實(shí)例氯材。

Redis哨兵

這里的哨兵有兩個(gè)作用

  • 通過(guò)發(fā)送命令,讓Redis服務(wù)器返回監(jiān)控其運(yùn)行狀態(tài)硝岗,包括主服務(wù)器和從服務(wù)器氢哮。

  • 當(dāng)哨兵監(jiān)測(cè)到master宕機(jī),會(huì)自動(dòng)將slave切換成master型檀,然后通過(guò)發(fā)布訂閱模式通知其他的從服務(wù)器冗尤,修改配置文件,讓它們切換主機(jī)胀溺。

然而一個(gè)哨兵進(jìn)程對(duì)Redis服務(wù)器進(jìn)行監(jiān)控裂七,可能會(huì)出現(xiàn)問(wèn)題,為此仓坞,我們可以使用多個(gè)哨兵進(jìn)行監(jiān)控背零。各個(gè)哨兵之間還會(huì)進(jìn)行監(jiān)控,這樣就形成了多哨兵模式无埃。

用文字描述一下故障切換(failover)的過(guò)程徙瓶。假設(shè)主服務(wù)器宕機(jī)毛雇,哨兵1先檢測(cè)到這個(gè)結(jié)果,系統(tǒng)并不會(huì)馬上進(jìn)行failover過(guò)程侦镇,僅僅是哨兵1主觀的認(rèn)為主服務(wù)器不可用灵疮,這個(gè)現(xiàn)象成為主觀下線。當(dāng)后面的哨兵也檢測(cè)到主服務(wù)器不可用壳繁,并且數(shù)量達(dá)到一定值時(shí)震捣,那么哨兵之間就會(huì)進(jìn)行一次投票,投票的結(jié)果由一個(gè)哨兵發(fā)起闹炉,進(jìn)行failover操作蒿赢。切換成功后,就會(huì)通過(guò)發(fā)布訂閱模式剩胁,讓各個(gè)哨兵把自己監(jiān)控的從服務(wù)器實(shí)現(xiàn)切換主機(jī)诉植,這個(gè)過(guò)程稱為客觀下線。這樣對(duì)于客戶端而言昵观,一切都是透明的晾腔。

二、Redis配置哨兵模式

配置3個(gè)哨兵和1主2從的Redis服務(wù)器來(lái)演示這個(gè)過(guò)程啊犬。

服務(wù)類型 是否是主服務(wù)器 IP地址 端口
Redis 192.168.11.128 6379
Redis 192.168.11.129 6379
Redis 192.168.11.130 6379
Sentinel - 192.168.11.128 26379
Sentinel - 192.168.11.129 26379
Sentinel - 192.168.11.130 26379
多哨兵監(jiān)控Redis

首先配置Redis的主從服務(wù)器灼擂,修改redis.conf文件如下

# 使得Redis服務(wù)器可以跨網(wǎng)絡(luò)訪問(wèn)
bind 0.0.0.0
# 設(shè)置密碼
requirepass "123456"
# 指定主服務(wù)器,注意:有關(guān)slaveof的配置只是配置從服務(wù)器觉至,主服務(wù)器不需要配置
slaveof 192.168.11.128 6379
# 主服務(wù)器密碼剔应,注意:有關(guān)slaveof的配置只是配置從服務(wù)器,主服務(wù)器不需要配置
masterauth 123456

上述內(nèi)容主要是配置Redis服務(wù)器语御,從服務(wù)器比主服務(wù)器多一個(gè)slaveof的配置和密碼峻贮。

配置3個(gè)哨兵,每個(gè)哨兵的配置都是一樣的应闯。在Redis安裝目錄下有一個(gè)sentinel.conf文件纤控,copy一份進(jìn)行修改

# 禁止保護(hù)模式
protected-mode no
# 配置監(jiān)聽(tīng)的主服務(wù)器,這里sentinel monitor代表監(jiān)控碉纺,mymaster代表服務(wù)器的名稱船万,可以自定義,192.168.11.128代表監(jiān)控的主服務(wù)器骨田,6379代表端口耿导,2代表只有兩個(gè)或兩個(gè)以上的哨兵認(rèn)為主服務(wù)器不可用的時(shí)候,才會(huì)進(jìn)行failover操作态贤。
sentinel monitor mymaster 192.168.11.128 6379 2
# sentinel author-pass定義服務(wù)的密碼舱呻,mymaster是服務(wù)名稱,123456是Redis服務(wù)器密碼
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456

上述關(guān)閉了保護(hù)模式悠汽,便于測(cè)試狮荔。

有了上述的修改胎撇,我們可以進(jìn)入Redis的安裝目錄的src目錄,通過(guò)下面的命令啟動(dòng)服務(wù)器和哨兵

# 啟動(dòng)Redis服務(wù)器進(jìn)程
./redis-server ../redis.conf
# 啟動(dòng)哨兵進(jìn)程
./redis-sentinel ../sentinel.conf

注意啟動(dòng)的順序殖氏。首先是主機(jī)(192.168.11.128)的Redis服務(wù)進(jìn)程晚树,然后啟動(dòng)從機(jī)的服務(wù)進(jìn)程,最后啟動(dòng)3個(gè)哨兵的服務(wù)進(jìn)程雅采。

三爵憎、Java中使用哨兵模式

/**
 * 測(cè)試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"));
        // 創(chuàng)建連接池
        JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig,"123456");
        // 獲取客戶端
        Jedis jedis = pool.getResource();
        // 執(zhí)行兩個(gè)命令
        jedis.set("mykey", "myvalue");
        String value = jedis.get("mykey");
        System.out.println(value);
    }
}

上面是通過(guò)Jedis進(jìn)行使用的,同樣也可以使用Spring進(jìn)行配置RedisTemplate使用婚瓜。

        <bean id = "poolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <!-- 最大空閑數(shù) -->
            <property name="maxIdle" value="50"></property>
            <!-- 最大連接數(shù) -->
            <property name="maxTotal" value="100"></property>
            <!-- 最大等待時(shí)間 -->
            <property name="maxWaitMillis" value="20000"></property>
        </bean>
        
        <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
            <constructor-arg name="sentinelConfig" ref="sentinelConfig"></constructor-arg>
            <property name="password" value="123456"></property>
        </bean>
        
        <!-- JDK序列化器 -->
        <bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
        
        <!-- String序列化器 -->
        <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
        
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
            <property name="connectionFactory" ref="connectionFactory"></property>
            <property name="keySerializer" ref="stringRedisSerializer"></property>
            <property name="defaultSerializer" ref="stringRedisSerializer"></property>
            <property name="valueSerializer" ref="jdkSerializationRedisSerializer"></property>
        </bean>
        
        <!-- 哨兵配置 -->
        <bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
            <!-- 服務(wù)名稱 -->
            <property name="master">
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <property name="name" value="mymaster"></property>
                </bean>
            </property>
            <!-- 哨兵服務(wù)IP和端口 -->
            <property name="sentinels">
                <set>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="192.168.11.128"></constructor-arg>
                        <constructor-arg name="port" value="26379"></constructor-arg>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="192.168.11.129"></constructor-arg>
                        <constructor-arg name="port" value="26379"></constructor-arg>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="192.168.11.130"></constructor-arg>
                        <constructor-arg name="port" value="26379"></constructor-arg>
                    </bean>
                </set>
            </property>
        </bean>

四宝鼓、哨兵模式的其他配置項(xiàng)

配置項(xiàng) 參數(shù)類型 作用
port 整數(shù) 啟動(dòng)哨兵進(jìn)程端口
dir 文件夾目錄 哨兵進(jìn)程服務(wù)臨時(shí)文件夾,默認(rèn)為/tmp巴刻,要保證有可寫入的權(quán)限
sentinel down-after-milliseconds <服務(wù)名稱><毫秒數(shù)(整數(shù))> 指定哨兵在監(jiān)控Redis服務(wù)時(shí)愚铡,當(dāng)Redis服務(wù)在一個(gè)默認(rèn)毫秒數(shù)內(nèi)都無(wú)法回答時(shí),單個(gè)哨兵認(rèn)為的主觀下線時(shí)間胡陪,默認(rèn)為30000(30秒)
sentinel parallel-syncs <服務(wù)名稱><服務(wù)器數(shù)(整數(shù))> 指定可以有多少個(gè)Redis服務(wù)同步新的主機(jī)沥寥,一般而言,這個(gè)數(shù)字越小同步時(shí)間越長(zhǎng)柠座,而越大邑雅,則對(duì)網(wǎng)絡(luò)資源要求越高
sentinel failover-timeout <服務(wù)名稱><毫秒數(shù)(整數(shù))> 指定故障切換允許的毫秒數(shù),超過(guò)這個(gè)時(shí)間妈经,就認(rèn)為故障切換失敗淮野,默認(rèn)為3分鐘
sentinel notification-script <服務(wù)名稱><腳本路徑> 指定sentinel檢測(cè)到該監(jiān)控的redis實(shí)例指向的實(shí)例異常時(shí),調(diào)用的報(bào)警腳本吹泡。該配置項(xiàng)可選骤星,比較常用

sentinel down-after-milliseconds配置項(xiàng)只是一個(gè)哨兵在超過(guò)規(guī)定時(shí)間依舊沒(méi)有得到響應(yīng)后,會(huì)自己認(rèn)為主機(jī)不可用爆哑。對(duì)于其他哨兵而言妈踊,并不是這樣認(rèn)為。哨兵會(huì)記錄這個(gè)消息泪漂,當(dāng)擁有認(rèn)為主觀下線的哨兵達(dá)到sentinel monitor所配置的數(shù)量時(shí),就會(huì)發(fā)起一次投票歪泳,進(jìn)行failover萝勤,此時(shí)哨兵會(huì)重寫Redis的哨兵配置文件,以適應(yīng)新場(chǎng)景的需要呐伞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末敌卓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子伶氢,更是在濱河造成了極大的恐慌趟径,老刑警劉巖瘪吏,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蜗巧,居然都是意外死亡掌眠,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門幕屹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蓝丙,“玉大人,你說(shuō)我怎么就攤上這事望拖∶斐荆” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵说敏,是天一觀的道長(zhǎng)鸥跟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)盔沫,這世上最難降的妖魔是什么医咨? 我笑而不...
    開(kāi)封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮迅诬,結(jié)果婚禮上腋逆,老公的妹妹穿的比我還像新娘。我一直安慰自己侈贷,他們只是感情好惩歉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著俏蛮,像睡著了一般撑蚌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搏屑,一...
    開(kāi)封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天争涌,我揣著相機(jī)與錄音,去河邊找鬼辣恋。 笑死亮垫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的伟骨。 我是一名探鬼主播饮潦,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼携狭!你這毒婦竟也來(lái)了继蜡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稀并,沒(méi)想到半個(gè)月后仅颇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碘举,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年忘瓦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殴俱。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡政冻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出线欲,到底是詐尸還是另有隱情明场,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布李丰,位于F島的核電站苦锨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏趴泌。R本人自食惡果不足惜舟舒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嗜憔。 院中可真熱鬧秃励,春花似錦、人聲如沸吉捶。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)呐舔。三九已至币励,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間珊拼,已是汗流浹背食呻。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留澎现,地道東北人仅胞。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像剑辫,于是被迫代替她去往敵國(guó)和親干旧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容