Redis Redis sentinel Failover

Redis sentinel 簡介與部署

吳建男 Lancelot Wu 2020/09/29 09:52:39
12682

 

環境

VM: Centos7

Redis: 5.0.7

 

主從模式(master-slave model)

簡介

實際應用的環境中,一般都是需要部署 Redis 集群來實現高可用以保障服務穩定地進行。Redis 集群最基本的模式即是主從模式,一台主機(Matser)配上一台或多台從機(Slave),如下圖所示:

Redis 主從架構模式下,主機和從機的數據完全一致,主機支持數據的寫入、讀取等各項操作,從機則支持與主機數據的同步和讀取; 也正因數據資料的一致性,可以將寫入的工作交由主機,讀取的工作交由從機,從而達到讀寫分離目的,而一主多從的配置更是適合讀多寫少的情境。

部署

接下來會展示在同一台主機(VM)上部署一主三從的架構,假設情境是已經先部署單一架構的Redis。為區分單一架構和主從架構,建立 redis_ms 的資料夾,並在此資料夾下建立4個資料夾 redis-9000()9001()9002()9003()。將單一架構的 redis 資料夾下的所有檔案複製到資料夾 redis-9000,接著將 redis-9000 下的 redis.conf 分別複製到9001~9003的資料夾。修改配置檔 redis.conf 設定如下:

Master node( port 9000):

1. bind 192.168.56.102 127.0.0.1  #若有設定本機IP 一定要配置在後面

2. protected-mode no  #允許外網訪問 redis

3. port 9000

4. daemonize yes  #後台運行

5. pidfile "/var/run/redis_9000.pid"  #可使用預設

6. logfile "/opt/redis_ms/9000.log"  #log 名稱和存放位置

7. dbfilename "dump-9000.rdb"  #Redis 數據持久化時的存放位置

8. dir "/opt/redis_ms"  #Redis 的工作目錄

9. requirepass "xxxx"  #主機認證密碼,optional

 

Slave node (port 9001~9003):

1. bind 192.168.56.102 127.0.0.1  #若有設定本機IP 一定要配置在後面

2. protected-mode no  #允許外網訪問 redis

3. port 9001

4. daemonize yes  #後台運行

5. pidfile "/var/run/redis_9001.pid"  #可使用預設

6. logfile "/opt/redis_ms/9001.log"  #log 名稱和存放位置

7. dbfilename "dump-9001.rdb"  #Redis 數據持久化時的存放位置

8. dir "/opt/redis_ms"  #Redis 的工作目錄

9. masterauth "xxxx"  #訪問主機密碼,與主機 requirepass 設置的密碼一樣

10.  replicaof 192.168.56.102 9000  #設定主機的從屬<IP> <Port>

 

若要允許外網訪問 redis,要先開放 port,指令如下:

1. systemctl start firewalld

2. sudo firewall-cmd --zone=public --add-port=9000/tcp --permanent

3. sudo firewall-cmd –reload

上面指令若沒有加上 “--permanent” 重新開機後會失效

 

查詢 port 是否有開放:

sudo firewall-cmd --zone=public --query-port=9000/tcp

 

測試

測試 Redis 主從架構是否能正常運作,透過主機(9000) redis-server 來啟動主從節點:

1.   切換到 redis_ms 的目錄下

2.   ./redis-9000/src/redis-server ./redis-9000/redis.conf  #啟動 Redis主節點,一定要先啟動

3.   ./redis-9000/src/redis-server ./9001/redis.conf  #啟動 Redis 從節點

4. ./redis-9000/src/redis-server ./9002/redis.conf  #啟動 Redis 從節點

5.   ./redis-9000/src/redis-server ./9003/redis.conf  #啟動 Redis 從節點

查看4台主從機是否有成功啟動:

透過 redis_ms/src/ 目錄下的 redis-cli 分別連線到各台機器。

 

連線到 master:

因為前面配置 master 時有設定密碼,因此要先認證之後才可進行操作。

認證成功後即可以進行其他操作,輸入 info replication 可以看到主從資訊。

連線到 slave:

可以看到連線之 redis instance 的角色及 master instance 的資訊。

 

測試資料讀寫:

master instance 寫入數據資料:

slave instance 讀取數據資料:

由上述可知由主節點或從節點取得的資料數據是一樣的。

 

哨兵模式(sentinel model)

主從模式實現了讀寫分離,並解決了數據備份和單一模式可能引發的效能問題,但其在使用上也有不便之處。因為客戶端連接到不同的 redis instance 時,都得要指定IP端口,若所連接的 instance 故障下線了,主從模式無法通知客戶端切換到另一個可用的 instance,只能靠手動去修改配置並重新取得新的連線。若是故障的是主節點,所有的從節點會因為沒有主節點而同步中斷,進而變成各自獨立的節點,即整個叢集無效,直至手動修改配置或是重啟主節點。

哨兵模式 Redis 的高可用性解決方案,可以管理多組主從實例,其架構如下圖:

哨兵模式主要執行以下四個任務:

1. Monitoring: sentinel 會持續地定期檢查主從節點是否正常運作

2. Notification: 當被監控的節點服務出現問題時,sentinel 會透過 API 向管理者或其他相關應用程序發送通知

3. Automatic failover: 當主節點未如期工作或無法正常服務時,sentinel 會將失效主節點下的其中一個從節點推選為新的主節點,並設定其他從節點使用新的主節點

4. Configuration provider: 為客戶端提供 service discovery,客戶端可以透過 sentinel 取得主節點的連線資訊,包括故障轉移後新的主節點位址

 

部署

基於前面架構的主從模式,我們為其增加部署哨兵系統。為了管理方便,我們將資料夾 redis-9000 下的 sentinel.conf 分別複製到9001~9003的資料夾並修改配置,下面僅只將和主從模式配置主要不同之處列出:

9001:

1. port 26381

2. sentinel auth-pass <master-name> <password>

        master-name: 自訂義,只能包含英文、數字和 ”. - _”這三個特殊符號,用來管理同一個叢集,如此便可達到管理多個叢集

        password: 主從模式中,主節點的密碼

        範例: sentinel auth-pass mymaster tsmp123

3. sentinel monitor <master-name> <ip> <redis-port> <quorum>

        master-name: 同上述2中的說明

        redis-port: redis master node port

        quorum:數字,指明當有多少個 sentinel 認為 master node 失效時,才算真正的失效

       範例: sentinel monitor mymaster 192.168.56.102 9000 2 

9002:

1. port 26382

9003:

1. port 26383

資料夾90029003下的 sentinel.conf配置,除了 port以及需要有各自檔名的配置如pidfilelogfiledbfilename 等之外,其餘部分都和 9001 中的配置一模一樣。

測試

測試當原本的 master node 下線後,sentinel 是否會自動 failover,接下來依序啟動 redis master node à redis slave node à sentinel node:

1. 切換到 redis_ms 的目錄下並依序啟動 sentinel 節點

2. ./redis-9000/src/redis-sentinel ./9001/sentinel.conf 

    #注意這邊執行的是 redis-sentinel

3. 重複步驟2,執行資料夾 90029003下的 sentinel.conf

 

查看4台主從節點以及 sentinel是否有成功啟動:

 

連線到任意一台 sentinel 並輸入 info sentinel可以得到目前監聽的主機、slave sentinel個數等相關資訊。

測試自動 failover

master node 停用,再透過 sentinel 查看相關資訊,可以看到監聽的主機節點已經改變(從 port 9000 --> 9003)。

連線到新的 master node(9003),可以發現 slave node 變成2台,看不到 9000 那台的相關資訊。

接著再把 9000 那台重啟,連線到 master node(9003)去查看主從相關資訊。

上圖可以看出 9000 重新上線後,並不會恢復到原先 master 的身分,而是被 sentinel 掛接到新的 master node 9003 之下,成為其 slave node之一。

 

哨兵基本原理和概念

1. 定時任務: 每個 sentinel 節點都有3個定時任務,通過這些任務可以發現增刪的節點和狀態。其任務如下:

    a. 通過向主從節點發送 info 命令獲取最新的主從結構

    b. 通過發布訂閱功能獲取其他哨兵節點的信息

    c. 通過向其他節點發送ping命令進行心跳檢測,判斷節點是否下線

2. 主觀下線和客觀下線

    主觀下線: 在心跳檢測的定時任務中,如果其他節點超過一定時間沒有回覆,當前的哨兵節點就會主觀地將其認定為主觀下線(該節點不可用)

    客觀下線: 哨兵節點對主節點進行主觀下線後,會通過 sentinel is-master-down-by-addr 命令詢問其他哨兵節點該主節點的狀態;如果判斷主節點下線的哨兵數量達到一定數值,則對該主節點認定為客觀下線(該節點不可用)

3. 哨兵領導者選舉:

    當主節點被判斷客觀下線以後,各個哨兵節點會選出一個哨兵節點領導者,並由該領導者節點進行故障轉移操作

4. 故障轉移:

    a. 在從節點中選擇新的主節點:先過濾掉不健康的從節點,接著選擇的原則(順序)是

        i. 選擇 slave-priority 優先級最高的從節點

        ii. 選擇複製偏移量最大的從節點

        iii. 選擇 runid 最小(最早啟動)的從節點

    b. 更新主從狀態:

        新的主節點選出後,會將其餘的節點更新為此新主節點的從結點;另外若原先的主節點重新上線後,會成為此新主節點的從結點

    c. 通知客戶端:

        節點狀態更新後, sentinel 會通知客戶端節點變更訊息,客會端也會重新連結到新的主節點

經由上述幾個關鍵的概念,我們就可以大致上了解哨兵的工作原理。

 

參考文獻

1. Redis

    https://redis.io

2. CentOS下Redis部署記錄(單機+主從+哨兵+集群)

    http://www.appblog.cn/2017/12/17/CentOS%E4%B8%8BRedis%E9%83%A8%E7%BD%B2%E8%AE%B0%E5%BD%95%EF%BC%88%E5%8D%95%E6%9C%BA+%E4%B8%BB%E4%BB%8E+%E5%93%A8%E5%85%B5+%E9%9B%86%E7%BE%A4%EF%BC%89/

3. 實現故障恢復自動化:詳解Redis哨兵技術

    https://kknews.cc/zh-tw/news/qgqxxlb.html

4. 淺談 Redis Sentinel

    https://blog.csdn.net/qq2430/article/details/80679439?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4

 

吳建男 Lancelot Wu