一步步實現redis+sentinel雙機熱備

前言

前些天一直在忙線上環境部署的事情,初步想的是,nginx(keepalive雙機熱備)+3(tomcat)+2redis(雙機熱備),可是後來因爲阿里雲服務器經典網絡不提供虛擬IP,沒法使用keepalive,nginx雙機熱備只能暫時先放棄,退而求其次,採用nginx+3tomcat+2redis(雙機熱備)。nginx+tomcat因爲以前配置過,因此重點就落在redis雙機熱備上,畢竟是線上系統,適當的抗災能力仍是須要的,咱可不能像測試系統那麼去玩,不然黑鍋就有的背了,畢竟碼代碼賺點生活費也不容易。nginx

在網上也查了一些資料,redis集羣實現大概有如下幾種方式:redis

1.redis-cluster,官方提供的集羣搭建方案(過於重量級,比較適合後期數據量較大的時候的使用)數據庫

2.redis+keepalive(因爲咱們使用的阿里雲服務器不支持虛擬IP,因此這套方案也就夭折了)vim

3.redis+zookeeper(須要引入zookeeper,對現有代碼變更較大)tomcat

4.redis+sentinel(redis自帶監控中間件)(代碼變更小,配置少,並且能知足雙機熱備的需求)bash

基於咱們目前的狀況以及需求,通過初略對比,咱們團隊決定選用第四種方案redis+sentinel實現雙機熱備。服務器

準備工做

1.安裝redis-001(主)

$ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
$ tar xzf redis-3.2.3.tar.gz
$ mv redis-3.2.3 redis-001
$ cd redis-001
$ make

2.安裝redis-002(從)

$ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
$ tar xzf redis-3.2.3.tar.gz
$ mv redis-3.2.3 redis-002
$ cd redis-002
$ make

3.修改redis-002端口爲6380

$ cd /usr/tools/redis-002/
$ vim redis.conf
...找到port 6379改成6380...

4.修改redis默認配置

a.關閉ip綁定,註釋redis.conf中bind 127.0.0.1網絡

b.關閉保護模式,將protected-mode yes改成protected-mode no架構

5.啓動redis-001,redis-002

$ cd tools/redis-001/
$ ./src/redis-server redis.conf

出現如下信息就表示啓動成功了:socket

12513:M 09 Oct 11:15:49.061 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
12513:M 09 Oct 11:15:49.061 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
12513:M 09 Oct 11:15:49.061 * DB loaded from disk: 0.000 seconds
12513:M 09 Oct 11:15:49.061 * The server is now ready to accept connections on port 6379

redis主從複製

1.redis 複製的特色

    1). 同一個Master能夠同步多個Slaves。
    2). Slave一樣能夠接受其它Slaves的鏈接和同步請求,這樣能夠有效的分載Master的同步壓力。所以咱們能夠將Redis的Replication架構視爲圖結構。
    3). Master Server是以非阻塞的方式爲Slaves提供服務。因此在Master-Slave同步期間,客戶端仍然能夠提交查詢或修改請求。
    4). Slave Server一樣是以非阻塞的方式完成數據同步。在同步期間,若是有客戶端提交查詢請求,Redis則返回同步以前的數據。
    5). 爲了分載Master的讀操做壓力,Slave服務器能夠爲客戶端提供只讀操做的服務,寫服務仍然必須由Master來完成。即使如此,系統的伸縮性仍是獲得了很大的提升。
    6). Master能夠將數據保存操做交給Slaves完成,從而避免了在Master中要有獨立的進程來完成此操做。

2.redis複製原理

    在Slave啓動並鏈接到Master以後,它將主動發送一個SYNC命令。此後Master將啓動後臺存盤進程,同時收集全部接收到的用於修改數據集的命令,在後臺進程執行完畢後,Master將傳送整個數據庫文件到Slave,以完成一次徹底同步。而Slave服務器在接收到數據庫文件數據以後將其存盤並加載到內存中。此後,Master繼續將全部已經收集到的修改命令,和新的修改命令依次傳送給Slaves,Slave將在本次執行這些數據修改命令,從而達到最終的數據同步。
    若是Master和Slave之間的連接出現斷連現象,Slave能夠自動重連Master,可是在鏈接成功以後,一次徹底同步將被自動執行。

3.redis主從配置

前面也說了,redis主從配置很簡單,只須要一個slaveof就能夠搞定。

鏈接redis-002,執行slaveof 192.168.231.130 6379:

C:\Users\lenovo\Desktop\redis>D:
D:\>cd D:\Program Files\Redis-x64-3.0.5
D:\Program Files\Redis-x64-3.0.5>redis-cli.exe -h 192.168.231.130 -p 6380
192.168.231.130:6380> slaveof 192.168.231.130 6379
OK
192.168.231.130:6380>

執行完成後,能夠看到服務器上redis-001控制檯輸出如下內容:

12513:M 09 Oct 11:15:49.061 * DB loaded from disk: 0.000 seconds
12513:M 09 Oct 11:15:49.061 * The server is now ready to accept connections on port 6379
12513:M 09 Oct 11:41:59.371 * Slave 192.168.231.130:6380 asks for synchronization
12513:M 09 Oct 11:41:59.371 * Full resync requested by slave 192.168.231.130:6380
12513:M 09 Oct 11:41:59.371 * Starting BGSAVE for SYNC with target: disk
12513:M 09 Oct 11:41:59.372 * Background saving started by pid 13673
13673:C 09 Oct 11:41:59.388 * DB saved on disk
13673:C 09 Oct 11:41:59.388 * RDB: 6 MB of memory used by copy-on-write
12513:M 09 Oct 11:41:59.462 * Background saving terminated with success
12513:M 09 Oct 11:41:59.462 * Synchronization with slave 192.168.231.130:6380 succeeded

redis-002控制檯輸出:

13581:S 09 Oct 11:41:59.361 * Connecting to MASTER 192.168.231.130:6379
13581:S 09 Oct 11:41:59.370 * MASTER <-> SLAVE sync started
13581:S 09 Oct 11:41:59.370 * Non blocking connect for SYNC fired the event.
13581:S 09 Oct 11:41:59.371 * Master replied to PING, replication can continue...
13581:S 09 Oct 11:41:59.371 * Partial resynchronization not possible (no cached master)
13581:S 09 Oct 11:41:59.374 * Full resync from master: e2f4e2608956ea6392482c2e0a9429efdebd2b53:1
13581:S 09 Oct 11:41:59.462 * MASTER <-> SLAVE sync: receiving 76 bytes from master
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Flushing old data
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Loading DB in memory
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Finished with success

可是這樣作的話,重啓redis-002後又會復原,因此一般咱們會直接修改redis-002配置文件redis.conf,在末尾加上slaveof 192.168.231.130 6379部分,就永久有效了。

如今咱們往redis-001中寫入數據,就能夠從redis-002中查詢出來了,咱們來測試一下,往redis-001中寫入key爲name,value爲osc的數據。

192.168.231.130:6379> set name osc
OK
192.168.231.130:6379> keys *
1) "name"
192.168.231.130:6379>

查詢redis-002中的數據,會發現一樣存在name的key,而且值爲osc 

192.168.231.130:6380> keys *
1) "name"
192.168.231.130:6380> get name
"osc"
192.168.231.130:6380>

到目前爲止,redis主從複製已經配置成功了,接下來就要開始重點工做,配置雙機熱備。

redis+sentinel雙機熱備

1.理論概念

    雙機熱備特指基於高可用系統中的兩臺服務器的熱備(或高可用),因兩機高可用在國內使用較多,故得名雙機熱備,雙機高可用按工做中的切換方式分爲:主-備方式(Active-Standby方式)和雙主機方式(Active-Active方式),主-備方式即指的是一臺服務器處於某種業務的激活狀態(即Active狀態),另外一臺服務器處於該業務的備用狀態(即Standby狀態)。而雙主機方式即指兩種不一樣業務分別在兩臺服務器上互爲主備狀態(即Active-Standby和Standby-Active狀態)。

大白話就是,當主服務器掛了以後,從服務器立馬切換爲主服務器繼續工做,當原先主服務器修復完善啓動後,會自動充當從服務器的角色繼續工做。這樣就很好的避免了,因爲一臺主機出現故障,系統掛點的現象出現。

Sentinel(哨兵)是用於監控redis集羣中Master狀態的工具,已經集成在redis官方版本中,能夠直接配置使用。

2.Sentinel命令

       PING :返回 PONG 。
       SENTINEL masters :列出全部被監視的主服務器,以及這些主服務器的當前狀態;
       SENTINEL slaves <master name> :列出給定主服務器的全部從服務器,以及這些從服務器的當前狀態;
       SENTINEL get-master-addr-by-name <master name> : 返回給定名字的主服務器的 IP 地址和端口號。 若是這個主服務器正在執行故障轉移操做, 或者針對這個主服務器的故障轉移操做已經完成, 那麼這個命令返回新的主服務器的 IP 地址和端口號;
       SENTINEL reset <pattern> : 重置全部名字和給定模式 pattern 相匹配的主服務器。 pattern 參數是一個 Glob 風格的模式。 重置操做清楚主服務器目前的全部狀態, 包括正在執行中的故障轉移, 並移除目前已經發現和關聯的, 主服務器的全部從服務器和 Sentinel ;
       SENTINEL failover <master name> : 當主服務器失效時, 在不詢問其餘 Sentinel 意見的狀況下, 強制開始一次自動故障遷移。

客戶端能夠經過SENTINEL get-master-addr-by-name <master name>獲取當前的主服務器IP地址和端口號,以及SENTINEL slaves <master name>獲取全部的Slaves信息

3.雙機熱備配置

a.關閉redis-001與redis-002

b.在redis-001和redis-002配置sentinel.conf中加上如下配置信息:

sentinel monitor mymaster 192.168.231.130 6379 1

c.修改redis-002 sentinel.conf監聽端口:

​$ cd /usr/tools/redis-002/
$ vim sentinel.conf
...找到port 26379改成26380...
port 26380

d.分別啓動redis-001(主)與redis-002(從),redis 服務和sentinel服務

​$ cd /usr/tools/redis-002/
$ ./src/redis-server redis.conf
$ ./src/redis-sentinel sentinel.conf
​$ cd /usr/tools/redis-001/
$ ./src/redis-server redis.conf
$ ./src/redis-sentinel sentinel.conf

此時在主從redis,sentinel控制檯會出現如下信息:

14677:X 09 Oct 14:04:49.633 # Sentinel ID is 7b8fdc1e5e47426b0d62a3ddd22ede0fd712f452
14677:X 09 Oct 14:04:49.633 # +monitor master mymaster 192.168.231.130 6379 quorum 1
14677:X 09 Oct 14:04:49.634 * +slave slave 192.168.231.130:6380 192.168.231.130 6380 @ mymaster 192.168.231.130 6379
14677:X 09 Oct 14:05:53.727 * +sentinel sentinel 31e660153984b606951c564395bdc8e193943f0b 192.168.231.130 26380 @ mymaster 192.168.231.130 6379

e.測試結果:

鏈接主服務器sentinel,注意端口是sentinel.conf中配置的端口

根據前面描述的sentinel命令查詢主服務器信息:

192.168.231.130:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6379"
    7) "runid"
    8) "fafb94fe9bff119e8a97f9183e3bcb5561933631"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "671"
   19) "last-ping-reply"
   20) "671"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "4904"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "205675"
   29) "config-epoch"
   30) "0"
   31) "num-slaves"
   32) "1"
   33) "num-other-sentinels"
   34) "1"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
192.168.231.130:26379>

查詢從服務器信息:

192.168.231.130:26379> SENTINEL slaves mymaster
1)  1) "name"
    2) "192.168.231.130:6380"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6380"
    7) "runid"
    8) "feabcfa65e69778e877ca0bd95adb9d642f6522f"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "928"
   19) "last-ping-reply"
   20) "928"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "7332"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "388802"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "192.168.231.130"
   35) "master-port"
   36) "6379"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "472844"
192.168.231.130:26379>

如今,咱們來關閉端口爲6379主redis-001服務器,看看會出現什麼狀況,此時redis-002控制檯會出現如下信息:

14735:S 09 Oct 14:15:47.618 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:48.628 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:48.628 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:48.628 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:49.638 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:49.638 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:49.638 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:50.648 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:50.648 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:50.648 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:51.659 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:51.659 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:51.659 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:52.669 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:52.669 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:52.669 # Error condition on socket for SYNC: Connection refused
14735:M 09 Oct 14:15:53.459 * Discarding previously cached master state.
14735:M 09 Oct 14:15:53.459 * MASTER MODE enabled (user request from 'id=5 addr=192.168.231.130:53187 fd=7 name=sentinel-7b8fdc1e-cmd age=23 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=0 qbuf-free=32768 obl=36 oll=0 omem=0 events=r cmd=exec')
14735:M 09 Oct 14:15:53.463 # CONFIG REWRITE executed with success.

從日誌能夠看出,服務器會通過屢次鏈接主服務器失敗後,斷定主服務器故障,會對配置文件進行重寫(CONFIG REWRITE executed with success),咱們再去看看從服務器的配置文件redis.conf,會發現以前在末尾加上的slaveof 192.168.231.130 6379不見了,這就說明當sentinel監測到主服務器掛掉以後,自動將從服務器切換爲主服務器。

咱們再來看看主從服務器sentinel控制檯輸出了信息:

主sentinel:

14677:X 09 Oct 14:15:54.384 # +promoted-slave slave 192.168.231.130:6380 192.168.231.130 6380 @ mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.384 # +failover-state-reconf-slaves master mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.456 # +failover-end master mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.456 # +switch-master mymaster 192.168.231.130 6379 192.168.231.130 6380
14677:X 09 Oct 14:15:54.456 * +slave slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380
14677:X 09 Oct 14:16:04.479 # +sdown slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380

從sentinel:

14688:X 09 Oct 14:15:53.223 # +sdown master mymaster 192.168.231.130 6379
14688:X 09 Oct 14:15:53.223 # +odown master mymaster 192.168.231.130 6379 #quorum 1/1
14688:X 09 Oct 14:15:53.223 # Next failover delay: I will not start a failover before Sun Oct  9 14:21:53 2016
14688:X 09 Oct 14:15:54.461 # +config-update-from sentinel 7b8fdc1e5e47426b0d62a3ddd22ede0fd712f452 192.168.231.130 26379 @ mymaster 192.168.231.130 6379
14688:X 09 Oct 14:15:54.461 # +switch-master mymaster 192.168.231.130 6379 192.168.231.130 6380
14688:X 09 Oct 14:15:54.461 * +slave slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380
14688:X 09 Oct 14:16:04.483 # +sdown slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380

從上面日誌信息能夠看出,主從確實已經切換成功了,最後咱們來看看實際狀況是否是那樣的,打開命令行執行查詢主從信息命令,看看會出現什麼結果:

192.168.231.130:26379> SENTINEL get-master-addr-by-name mymaster
1) "192.168.231.130"
2) "6380"
192.168.231.130:26379>
192.168.231.130:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6380"
    7) "runid"
    8) "bb4fe3dece04db30c29f6650f1edd4d3689da751"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "14"
   19) "last-ping-reply"
   20) "14"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "4648"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "847746"
   29) "config-epoch"
   30) "1"
   31) "num-slaves"
   32) "1"
   33) "num-other-sentinels"
   34) "1"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
192.168.231.130:26379>

到這裏基本已經部署完畢了,再去啓動原先主服務器redis-001,會發現此時的redis-001變成了從服務器,接下來的內容因爲與前面重複較多,我就不演示了。

注意事項

1.一步一步來,先配置主從複製,再配置主從切換

2.啓動順序不要弄錯了,先啓動主服務器的redis與sentinel,再啓動從服務器redis與sentinel,若是遇到失敗狀況,因爲sentinel啓動後會自動修改和生成部分配置信息,爲避免衝突浪費時間,建議直接刪除配置文件,從新配置。

3.若是redis有密碼的話,須要在主從服務器redis.conf中都加上:

masterauth <password>

以及在主從服務器sentinel.conf加上:

sentinel auth-pass mymaster <password>

二者密碼一致。

4.daemonize yes,啓用保護進程
protected-mode no,關閉保護模式

另附

具體程序代碼修改部分,能夠參考《JedisSentinelPool的相關配置與操做》

《福利送上,未滿十八歲勿點》

相關文章
相關標籤/搜索