redis 主從復(fù)制與哨兵模式

上一篇文章我們簡(jiǎn)單介紹了redis api 的使用方式,本節(jié)的內(nèi)容,我們講一下他是如何保證高可用的。
測(cè)試版本是redis-3.2.11,從官網(wǎng)拉去到源碼后,進(jìn)行編譯make,就會(huì)在src目錄下看到很多可執(zhí)行文件,例如redis-server,redis-cli,redis-sentinel等大家耳熟能詳?shù)摹?/p>

首先我們解釋一下主從的區(qū)別:主對(duì)于數(shù)據(jù)可讀可寫。從默認(rèn)是只讀不寫的。當(dāng)從連接上主時(shí),主會(huì)將數(shù)據(jù)同步到從上。詳細(xì)的內(nèi)容我們可以參考一下Redis主從同步原理-SYNC這篇文章講的還是很詳細(xì)的。

哨兵:當(dāng)主掛掉,哨兵可以通過選舉從從服務(wù)器中選擇一臺(tái)作為主,提供高可用的方案。注意當(dāng)原來的主恢復(fù)時(shí),也將成為現(xiàn)在主的從服務(wù)器。

概念解釋完了,我們來搭建環(huán)境。首先我們搭建的是主從。從最基本的一主一從開始。

主的配置相較于默認(rèn)的配置文件修改的點(diǎn),主要修改的是存放數(shù)據(jù)的目錄而已

bind 127.0.0.1
port 6379
pidfile "/Users/olifer/middle/redis/master/redis_6379.pid"
dir "/Users/olifer/middle/redis/master"

配置好了我們啟動(dòng)服務(wù)redis-server redis.conf , 如果看到下面的文字,說明啟動(dòng)成功

783:M 02 Dec 19:19:39.829 # Server started, Redis version 3.2.11
783:M 02 Dec 19:19:39.829 * The server is now ready to accept connections on port 6379

從的配置也相對(duì)較為簡(jiǎn)單,端口改一下6380,最為主要的是配置slaveof,指明他的主是誰

bind 127.0.0.1
port 6380
pidfile "/Users/olifer/middle/redis/slave/redis_6380.pid"
dir "/Users/olifer/middle/redis/slave1"

slaveof 127.0.0.1 6379

配置好了我們啟動(dòng)服務(wù)redis-server redis.conf , 如果看到下面的文字,說明啟動(dòng)成功

900:S 02 Dec 19:22:16.682 # Server started, Redis version 3.2.11
900:S 02 Dec 19:22:16.682 * The server is now ready to accept connections on port 6380
900:S 02 Dec 19:22:16.684 * Connecting to MASTER 127.0.0.1:6379
900:S 02 Dec 19:22:16.684 * MASTER <-> SLAVE sync started

通過slave的日志我們可以看出,啟動(dòng)成功,暴露端口為6380,并且連接上了自己的主6379,并且開始了同步數(shù)據(jù)。

這時(shí)候我們可以看一下主的日志,同樣也能得到類似的信息,從主的日志可以看出,從確實(shí)連接上了主,并且愛是同步數(shù)據(jù)到從服務(wù)器,這個(gè)數(shù)據(jù)同步的過程我們會(huì)在下一篇文章中講述。

783:M 02 Dec 19:22:16.685 * Slave 127.0.0.1:6380 asks for synchronization
783:M 02 Dec 19:22:16.685 * Full resync requested by slave 127.0.0.1:6380
783:M 02 Dec 19:22:16.685 * Starting BGSAVE for SYNC with target: disk
783:M 02 Dec 19:22:16.685 * Background saving started by pid 901
901:C 02 Dec 19:22:16.685 * DB saved on disk
783:M 02 Dec 19:22:16.760 * Background saving terminated with success
783:M 02 Dec 19:22:16.761 * Synchronization with slave 127.0.0.1:6380 succeeded

目前為止我們一個(gè)redis的主從就這么搭建好了,是不是超級(jí)簡(jiǎn)單,搭建好了,我們就需要驗(yàn)證功能了。我們使用redis-cli連接到主上,也就是6379。當(dāng)然你也可以不用指定-p,因?yàn)槟J(rèn)的就是6379,這樣就可以進(jìn)入到redis shell的操作界面。我們簡(jiǎn)單的set一個(gè)值

redis-cli -p 6379
127.0.0.1:6379> set name olifer
OK

這時(shí)候我們驗(yàn)證一下從服務(wù)器的數(shù)據(jù)有沒有同步過來。

redis-cli -p 6380
127.0.0.1:6380> get name
"olifer"

和我們預(yù)想的是一致的,我們從從的服務(wù)器上可以獲取到主的數(shù)據(jù),更為確切的說,是主從數(shù)據(jù)進(jìn)行了準(zhǔn)實(shí)時(shí)的同步,所以可以從從服務(wù)器上獲取到數(shù)據(jù)。

我們可以往從服務(wù)器上設(shè)置值嗎?實(shí)踐是檢驗(yàn)真理的唯一的方式,試一下

127.0.0.1:6380> set age 123
(error) READONLY You can't write against a read only slave.

發(fā)現(xiàn)報(bào)錯(cuò)了,slave默認(rèn)情況下是不能寫數(shù)據(jù),只能讀取數(shù)據(jù)。當(dāng)然這個(gè)也是可以設(shè)置的,在從的配置文件中有這個(gè)一個(gè)配置

slave-read-only yes

從名字我們就看出來他是只讀的,如果我們想slave也可以寫,我們可以修改此配置為no,之后我們重啟一下,看結(jié)果就可以了。

127.0.0.1:6380> set age 123
OK

所以一些有用的配置大家還是屬性一下吧。

現(xiàn)在大家思考一個(gè)問題,主從結(jié)構(gòu)只能保證數(shù)據(jù)有備份,但是如果主掛掉了,怎么辦,整個(gè)服務(wù)就不可用了,這顯然是個(gè)大問題。當(dāng)然redis也幫我們考慮到了這一點(diǎn)。解決方案就是哨兵。他可以作為一個(gè)第三方,監(jiān)控著我們主節(jié)點(diǎn)的狀態(tài),當(dāng)發(fā)現(xiàn)主掛掉后,就會(huì)從這個(gè)主的從服務(wù)器中進(jìn)行選舉,推選出一個(gè)新主,同時(shí)slave也切換成這個(gè)新主的slave,如果原來的主重啟成功了也不會(huì)再次成為主了,而是作為slave掛到新主上。現(xiàn)在我們?cè)僦鸩竭M(jìn)行驗(yàn)證。因?yàn)樯婕暗竭x舉所以一個(gè)slave肯定是不夠的,所以最少是兩個(gè),上面我們的6380已經(jīng)是一個(gè)從了,所以我們?cè)傩陆ㄒ粋€(gè)6381的從服務(wù)器。配置如下

bind 127.0.0.1
port 6381
pidfile "/Users/olifer/middle/redis/slave/redis_6381.pid"
dir "/Users/olifer/middle/redis/slave2"

slaveof 127.0.0.1 6379

啟動(dòng)redis-server redis-conf后出現(xiàn)下面的頁面,說明配置成功

1229:S 02 Dec 19:57:08.243 # Server started, Redis version 3.2.11
1229:S 02 Dec 19:57:08.243 * DB loaded from disk: 0.000 seconds
1229:S 02 Dec 19:57:08.243 * The server is now ready to accept connections on port 6381
1229:S 02 Dec 19:57:08.243 * Connecting to MASTER 127.0.0.1:6379

下面我們?cè)倥渲蒙诒?,其?shí)也是特別的簡(jiǎn)單,我們可以從redis的源文件中找到sentinel.conf配置文件,他就是哨兵的配置

port 26379
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 2

port不用多說,就是一個(gè)端口號(hào)。我們說一下這個(gè)配置,sentinel monitor mymaster 127.0.0.1 6379 1,我們給監(jiān)控的主節(jié)點(diǎn)起了個(gè)名字叫做mymaster,他的位置是127.0.0.1,端口是6379,主掛掉后我們要通過選舉獲得最新的主,所以1代表了法定的人數(shù),也就是有1臺(tái)服務(wù)器同意這個(gè)提案就可以。這個(gè)配置sentinel down-after-milliseconds mymaster 5000,表示master或slave 5s(默認(rèn)30秒)不能使用后標(biāo)記為s_down狀態(tài)。sentinel parallel-syncs mymaster 2,指定了在執(zhí)行故障轉(zhuǎn)移時(shí), 最多可以有多少個(gè)從服務(wù)器同時(shí)對(duì)新的主服務(wù)器進(jìn)行同步,配置完成后,開始啟動(dòng)

redis-sentinel sentinel.conf
1385:X 02 Dec 20:12:44.725 * Increased maximum number of open files to 10032 (it was originally set to 7168).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.11 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 1385
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

1385:X 02 Dec 20:12:44.726 # Sentinel ID is 104e563c9931120931c3594973cab424509c2646
1385:X 02 Dec 20:12:44.726 # +monitor master mymaster 127.0.0.1 6379 quorum 1
1385:X 02 Dec 20:12:44.727 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:12:44.728 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

從這個(gè)日志中我們可以看出,記錄了master的信息(127.0.0.1 6379),也記錄了slave的信息(127.0.0.1 6380,127.0.0.1 6381).我們可以進(jìn)入查看一下

redis-cli -p 26379

就可以查看一下master,slave包括哨兵的信息

sentinel master mymaster    //查看master的狀態(tài) 
sentinel slaves mymaster    //查看salves的狀態(tài)
sentinel sentinels mymaster //查看哨兵的狀態(tài)
info sentinel               //查看哨兵信息

我們的環(huán)境配置好了,就可以驗(yàn)證一些問題了。第一個(gè)問題當(dāng)主掛掉能否自動(dòng)切換,從slave中挑選一臺(tái)作為主。下面我們就把master shutdown.我們可以從哨兵的日志中發(fā)現(xiàn)一段這樣的日志

1385:X 02 Dec 20:26:49.199 # +sdown master mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:49.199 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
1385:X 02 Dec 20:26:49.199 # +new-epoch 1
1385:X 02 Dec 20:26:49.199 # +try-failover master mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:49.208 # +vote-for-leader 104e563c9931120931c3594973cab424509c2646 1
1385:X 02 Dec 20:26:49.208 # +elected-leader master mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:49.208 # +failover-state-select-slave master mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:49.274 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:49.274 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:49.379 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:50.309 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:50.309 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:50.391 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:51.332 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:52.392 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:52.447 # +failover-end master mymaster 127.0.0.1 6379
1385:X 02 Dec 20:26:52.447 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
1385:X 02 Dec 20:26:52.447 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
1385:X 02 Dec 20:26:52.447 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
1385:X 02 Dec 20:26:57.489 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

每個(gè)sentinel會(huì)向其它sentinal、master、slave定時(shí)發(fā)送消息,以確認(rèn)對(duì)方是否“活”著,如果發(fā)現(xiàn)對(duì)方在指定時(shí)間(可配置)內(nèi)未回應(yīng),則暫時(shí)認(rèn)為對(duì)方已掛(所謂的“主觀認(rèn)為宕機(jī)” Subjective Down,簡(jiǎn)稱SDOWN)。若“哨兵群”中的多數(shù)sentinel,都報(bào)告某一master沒響應(yīng),系統(tǒng)才認(rèn)為該master"徹底死亡"(即:客觀上的真正down機(jī),Objective Down,簡(jiǎn)稱ODOWN),通過一定的vote算法,從剩下的slave節(jié)點(diǎn)中,選一臺(tái)提升為master,然后自動(dòng)修改相關(guān)配置。到最后通過選舉決定了6380作為新的主,同時(shí)將6379(已經(jīng)掛掉)與6381(存活)作為 6380 的slave。這時(shí)候我們看一下各個(gè)節(jié)點(diǎn)的配置文件。首先看一下6380,原來配置文件中的slaveof 127.0.0.1 6379 已經(jīng)刪掉了,說明他已經(jīng)不是從節(jié)點(diǎn)了,那么他就變成主節(jié)點(diǎn)了。在看一下6381 ,他的配置已經(jīng)從原來的slaveof 127.0.0.1 6379 變成了 slaveof 127.0.0.1 6380。看一下哨兵的配置文件,最下面多了幾行

# Generated by CONFIG REWRITE
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-slave mymaster 127.0.0.1 6379
sentinel known-slave mymaster 127.0.0.1 6381
sentinel current-epoch 1

說明哨兵也已經(jīng)做好了切換。6379這時(shí)候在哨兵的眼里就是一個(gè)slave了,所以他重啟后,不可能變成主了,只能是從了。我們現(xiàn)在啟動(dòng)6379 ,在哨兵的日志中增加了下面兩行

1385:X 02 Dec 20:40:09.929 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
1385:X 02 Dec 20:40:19.872 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380

在6379的redis-conf文件的最后面,增加了兩行

# Generated by CONFIG REWRITE
slaveof 127.0.0.1 6380

所以總的過程就是當(dāng)哨兵發(fā)現(xiàn)主掛掉后,會(huì)通過選舉選出新主,slave的關(guān)系進(jìn)行切換。整個(gè)過程順滑、完整。不得不說做的很漂亮啊。

參考文章:
redis可用性提升(哨兵sentinel)配置示例
redis哨兵配置主從

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • "只要站在風(fēng)口,豬也能飛上天",這幾年網(wǎng)店,團(tuán)購,APP,智能硬件一波接著一波,今年人工智能又要"火".弄得我都不...
    xieyan0811閱讀 354評(píng)論 0 1
  • Crop 裁剪圖片Repo(備用): https://github.com/jeduan/cordova-plug...
    待花謝花開閱讀 802評(píng)論 0 1
  • 寫這篇文章的時(shí)候,我剛與一玻璃心的人心塞至此,但現(xiàn)在我只想平心氣和的寫完這篇文章,希望我以后不要輕易忘記對(duì)自己的告...
    葉子吶閱讀 3,795評(píng)論 0 0

友情鏈接更多精彩內(nèi)容