爲了解決單點問題,保證數據的安全性,Redis 提供了複製機制,用於知足故障恢復和負載均衡等需求。經過複製機制,Redis 能夠經過多個副本保證數據的安全性,從而提供高可用的基礎,Redis 的哨兵和集羣模式都是在複製基礎上實現高可用的。git
想要對兩個 Redis 節點創建主從複製關係,能夠經過如下三種方式來實現:github
slaveof {masterHost} {masterPort}
選項;--slaveof {masterHost} {masterPort}
參數;slaveof {masterHost} {masterPort}
命令。主從節點複製關係創建後,可使用 info replication
命令查看相關的複製狀態。須要注意的是每一個從節點只能有一個主節點,但主節點能夠同時擁有多個從節點,複製行爲是單向的,只能由主節點複製到從節點,所以從節點默認都是隻讀模式,即 slave-read-only
的值默認爲 yes
。redis
在啓動後,若是想要斷開復制關係,能夠經過在從節點上執行 slaveof no one
命令,此時從節點會斷開與主節點的複製關係,但並不會刪除原有的複製成功的數據,只是沒法再獲取主節點上的數據。算法
經過 slaveof 命令還能夠實現切換主節點的操做,命令以下:shell
slaveof {newMasterIp} {newMasterPort}
複製代碼
須要注意的是,當你從一個主節點切換到另一個主節點時,該從節點上的原有的數據會被徹底清除,而後再執行復制操做,從而保證該從節點上的數據和新主節點上的數據相同。安全
複製機制最主要的缺陷在於,一旦主節點出現故障,從節點沒法自動晉升爲主節點,須要經過手動切換來實現,這樣沒法達到故障的快速轉移,所以也不能實現高可用。基於這個緣由,就產生了哨兵模式。bash
哨兵模式的主要做用在於它可以自動完成故障發現和故障轉移,並通知客戶端,從而實現高可用。哨兵模式一般由一組 Sentinel 節點和一組(或多組)主從複製節點組成,架構以下:架構
Redis Sentinel 是一個特殊的 Redis 節點。在哨兵模式建立時,須要經過配置指定 Sentinel 與 Redis Master Node 之間的關係,而後 Sentinel 會從主節點上獲取全部從節點的信息,以後 Sentinel 會定時向主節點和從節點發送 info
命令獲取其拓撲結構和狀態信息。負載均衡
基於 Redis 的發佈訂閱功能, 每一個 Sentinel 節點會向主節點的 __sentinel__:hello
頻道上發送該 Sentinel 節點對於主節點的判斷以及當前 Sentinel 節點的信息 ,同時每一個 Sentinel 節點也會訂閱該頻道, 來獲取其餘 Sentinel 節點的信息以及它們對主節點的判斷。運維
經過以上兩步全部的 Sentinel 節點以及它們與全部的 Redis 節點之間都已經彼此感知到,以後每一個 Sentinel 節點會向主節點、從節點、以及其他 Sentinel 節點定時發送 ping 命令做爲心跳檢測, 來確認這些節點是否可達。
每一個 Sentinel 都會定時進行心跳檢查,當發現主節點出現心跳檢測超時的狀況時,此時認爲該主節點已經不可用,這種斷定稱爲主觀下線。以後該 Sentinel 節點會經過 sentinel ismaster-down-by-addr
命令向其餘 Sentinel 節點詢問對主節點的判斷, 當 quorum 個 Sentinel 節點都認爲該節點故障時,則執行客觀下線,即認爲該節點已經不可用。這也同時解釋了爲何必須須要一組 Sentinel 節點,由於單個 Sentinel 節點很容易對故障狀態作出誤判。
這裏 quorum 的值是咱們在哨兵模式搭建時指定的,後文會有說明,一般爲
Sentinel節點總數/2+1
,即半數以上節點作出主觀下線判斷就能夠執行客觀下線。
由於故障轉移的工做只須要一個 Sentinel 節點來完成,因此 Sentinel 節點之間會再作一次選舉工做, 基於 Raft 算法選出一個 Sentinel 領導者來進行故障轉移的工做。 被選舉出的 Sentinel 領導者進行故障轉移的具體步驟以下:
slaveof no one
命令讓其成爲主節點。下面演示在單機上搭建哨兵模式,多機搭建步驟亦同。須要注意的是在實際生產環境中,爲了保證高可用,Sentinel 節點須要儘可能部署在不一樣主機上,同時爲了保證正常選舉,至少須要 3個 Sentinel 節點。
拷貝三份 redis.conf
,分別命名爲 redis-6379.conf ,redis-6380.conf ,redis-6381.conf ,須要修改的配置項以下:
# redis-6379.conf
port 6379
daemonize yes #以守護進程的方式啓動
pidfile /var/run/redis_6379.pid #當Redis以守護進程方式運行時,Redis會把pid寫入該文件
logfile 6379.log
dbfilename dump-6379.rdb
dir /home/redis/data/
# redis-6380.conf
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile 6380.log
dbfilename dump-6380.rdb
dir /home/redis/data/
slaveof 127.0.0.1 6379
# redis-6381.conf
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
logfile 6381.log
dbfilename dump-6381.rdb
dir /home/redis/data/
slaveof 127.0.0.1 6379
複製代碼
拷貝三份 sentinel.conf
,分別命名爲 sentinel-26379.conf ,sentinel-26380.conf ,sentinel-26381.conf ,配置以下:
# sentinel-26379.conf
port 26379
daemonize yes
logfile 26379.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# sentinel-26380.conf
port 26380
daemonize yes
logfile 26380.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# sentinel-26381.conf
port 26381
daemonize yes
logfile 26381.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
複製代碼
分別啓動三個 Redis 節點,命令以下:
redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf
複製代碼
分別啓動三個Sentinel節點,命令以下:
redis-sentinel sentinel-26379.conf
redis-sentinel sentinel-26380.conf
redis-sentinel sentinel-26381.conf
複製代碼
使用 ps -ef | grep redis
命令查看進程,此時輸出應該以下:
可使用 info replication
命令查看 Redis 複製集的狀態,此時輸出以下。能夠看到 6379 節點爲 master 節點,而且有兩個從節點,分別爲 slave0 和 slave1,對應的端口爲 6380 和 6381:
可使用 info Sentinel
命令查看任意 Sentinel 節點的狀態,從最後一句輸出能夠看到 Sentinel 節點已經感知到 6379 的 master 節點,而且也知道它有兩個 slaves 節點;同時 Sentinel 節點彼此之間也感知到,共有 3 個 Sentinel 節點:
更多文章,歡迎訪問 [全棧工程師手冊] ,GitHub 地址:github.com/heibaiying/…