Redis哨兵模式
Sentinel(哨崗、哨兵)是Redis的高可用性(high availability)解決方案:由一個或多個Sentinel實例(instance)組成的Sentinel系統(system)可以監視任意多個主服務器,以及這些主服務器屬下的所有從服務器,並在被監視的主服務器進入下線狀態時,自動將下線主服務器屬下的某個從服務器升級為新的主服務器,然后由新的主服務器代替已下線的主服務器繼續處理命令請求。
——《Redis設計與實現》
准備環境和工具
系統環境
使用cat /etc/redhat-release查看
CentOS Linux release 7.8.2003 (Core)
安裝docker
這個就不介紹了,網上教程太多
安裝pip3
yum -y install python3-pip
安裝docker-compose
pip3 install docker-compose
我的目錄結構
Sentinel配置
Sentinel配置文件路徑:
/usr/local/etc/redis/sentinel/sentinel
redis-sentinel-1.conf
# bind 127.0.0.1
# 哨兵的端口號
# 因為各個哨兵節點會運行在單獨的Docker容器中
# 所以無需擔心端口重復使用
# 如果需要在單機
port 26379
# 設定密碼認證
requirepass 123456
# 配置哨兵的監控參數
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是為這個被監控的master起的名字
# ip是被監控的master的IP或主機名。因為Docker容器之間可以使用容器名訪問,所以這里寫master節點的容器名
# redis-port是被監控節點所監聽的端口號
# quorom設定了當幾個哨兵判定這個節點失效后,才認為這個節點真的失效了
sentinel monitor local-master 127.0.0.1 6379 2
# 連接主節點的密碼
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass local-master 123456
# master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
redis-sentinel-2.conf
# bind 127.0.0.1
# 哨兵的端口號
# 因為各個哨兵節點會運行在單獨的Docker容器中
# 所以無需擔心端口重復使用
# 如果需要在單機
port 26380
# 設定密碼認證
requirepass 123456
# 配置哨兵的監控參數
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是為這個被監控的master起的名字
# ip是被監控的master的IP或主機名。因為Docker容器之間可以使用容器名訪問,所以這里寫master節點的容器名
# redis-port是被監控節點所監聽的端口號
# quorom設定了當幾個哨兵判定這個節點失效后,才認為這個節點真的失效了
sentinel monitor local-master 127.0.0.1 6379 2
# 連接主節點的密碼
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass local-master 123456
# master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
redis-sentinel-3.conf
# bind 127.0.0.1
# 哨兵的端口號
# 因為各個哨兵節點會運行在單獨的Docker容器中
# 所以無需擔心端口重復使用
# 如果需要在單機
port 26381
# 設定密碼認證
requirepass 123456
# 配置哨兵的監控參數
# 格式:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# master-name是為這個被監控的master起的名字
# ip是被監控的master的IP或主機名。因為Docker容器之間可以使用容器名訪問,所以這里寫master節點的容器名
# redis-port是被監控節點所監聽的端口號
# quorom設定了當幾個哨兵判定這個節點失效后,才認為這個節點真的失效了
sentinel monitor local-master 127.0.0.1 6379 2
# 連接主節點的密碼
# 格式:sentinel auth-pass <master-name> <password>
sentinel auth-pass local-master 123456
# master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
Redis配置
Redis配置文件路徑:
/usr/local/etc/redis/sentinel/server
redis-master.conf
# bind 127.0.0.1
# 啟用保護模式
# 即在沒有使用bind指令綁定具體地址時
# 或在沒有設定密碼時
# Redis將拒絕來自外部的連接
# protected-mode yes
# 監聽端口
port 6379
# 啟動時不打印logo
# 這個不重要,想看logo就打開它
always-show-logo no
# 設定密碼認證
requirepass 123456
# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的鍵,會影響數據安全
# 另一方面 KEYS 命令會阻塞數據庫,在數據庫中存儲了大量數據時,該命令會消耗很長時間
# 期間對Redis的訪問也會被阻塞,而當鎖釋放的一瞬間,大量請求涌入Redis,會造成Redis直接崩潰
rename-command KEYS ""
# 此外還應禁止 FLUSHALL 和 FLUSHDB 命令
# 這兩個命令會清空數據,並且不會失敗
redis-slave1.conf
# bind 127.0.0.1
# 啟用保護模式
# 即在沒有使用bind指令綁定具體地址時
# 或在沒有設定密碼時
# Redis將拒絕來自外部的連接
# protected-mode yes
# 監聽端口
port 6380
# 啟動時不打印logo
# 這個不重要,想看logo就打開它
always-show-logo no
# 設定密碼認證
requirepass 123456
# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的鍵,會影響數據安全
# 另一方面 KEYS 命令會阻塞數據庫,在數據庫中存儲了大量數據時,該命令會消耗很長時間
# 期間對Redis的訪問也會被阻塞,而當鎖釋放的一瞬間,大量請求涌入Redis,會造成Redis直接崩潰
rename-command KEYS ""
# 此外還應禁止 FLUSHALL 和 FLUSHDB 命令
# 這兩個命令會清空數據,並且不會失敗
# 配置master節點信息
# 格式:
#slaveof <masterip> <masterport>
# 此處masterip所指定的redis-server-master是運行master節點的容器名
# Docker容器間可以使用容器名代替實際的IP地址來通信
slaveof 127.0.0.1 6379
# 設定連接主節點所使用的密碼
masterauth "123456"
redis-slave2.conf
# bind 127.0.0.1
# 啟用保護模式
# 即在沒有使用bind指令綁定具體地址時
# 或在沒有設定密碼時
# Redis將拒絕來自外部的連接
# protected-mode yes
# 監聽端口
port 6381
# 啟動時不打印logo
# 這個不重要,想看logo就打開它
always-show-logo no
# 設定密碼認證
requirepass 123456
# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的鍵,會影響數據安全
# 另一方面 KEYS 命令會阻塞數據庫,在數據庫中存儲了大量數據時,該命令會消耗很長時間
# 期間對Redis的訪問也會被阻塞,而當鎖釋放的一瞬間,大量請求涌入Redis,會造成Redis直接崩潰
rename-command KEYS ""
# 此外還應禁止 FLUSHALL 和 FLUSHDB 命令
# 這兩個命令會清空數據,並且不會失敗
# 配置master節點信息
# 格式:
#slaveof <masterip> <masterport>
# 此處masterip所指定的redis-server-master是運行master節點的容器名
# Docker容器間可以使用容器名代替實際的IP地址來通信
slaveof 127.0.0.1 6379
# 設定連接主節點所使用的密碼
masterauth "123456"
docker-compose配置
sentinel和redis-server分別用兩個docker-compose文件來管理
sentinel的docker-compose.yml文件
---
version: '3'
services:
redis-sentinel-1:
image: redis
container_name: redis-sentinel-1
restart: always
# 為了規避Docker中端口映射可能帶來的問題
# 這里選擇使用host網絡
network_mode: host
volumes:
- ./redis-sentinel-1.conf:/usr/local/etc/redis/redis-sentinel.conf
# 指定時區,保證容器內時間正確
environment:
TZ: "Asia/Shanghai"
sysctls:
net.core.somaxconn: '511'
command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
redis-sentinel-2:
image: redis
container_name: redis-sentinel-2
restart: always
network_mode: host
volumes:
- ./redis-sentinel-2.conf:/usr/local/etc/redis/redis-sentinel.conf
environment:
TZ: "Asia/Shanghai"
sysctls:
net.core.somaxconn: '511'
command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
redis-sentinel-3:
image: redis
container_name: redis-sentinel-3
restart: always
network_mode: host
volumes:
- ./redis-sentinel-3.conf:/usr/local/etc/redis/redis-sentinel.conf
environment:
TZ: "Asia/Shanghai"
sysctls:
net.core.somaxconn: '511'
command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
redis的docker-compose文件
---
version: '3'
services:
# 主節點的容器
redis-server-master:
image: redis
container_name: redis-server-master
restart: always
# 為了規避Docker中端口映射可能帶來的問題
# 這里選擇使用host網絡
network_mode: host
# 指定時區,保證容器內時間正確
environment:
TZ: "Asia/Shanghai"
volumes:
# 映射配置文件和數據目錄
- ./redis-master.conf:/usr/local/etc/redis/redis.conf
- ./data/redis-master:/data
sysctls:
# 必要的內核參數
net.core.somaxconn: '511'
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 從節點1的容器
redis-server-slave-1:
image: redis
container_name: redis-server-slave-1
restart: always
network_mode: host
depends_on:
- redis-server-master
environment:
TZ: "Asia/Shanghai"
volumes:
- ./redis-slave1.conf:/usr/local/etc/redis/redis.conf
- ./data/redis-slave-1:/data
sysctls:
net.core.somaxconn: '511'
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 從節點2的容器
redis-server-slave-2:
image: redis
container_name: redis-server-slave-2
restart: always
network_mode: host
depends_on:
- redis-server-master
environment:
TZ: "Asia/Shanghai"
volumes:
- ./redis-slave2.conf:/usr/local/etc/redis/redis.conf
- ./data/redis-slave-2:/data
sysctls:
net.core.somaxconn: '511'
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
哨兵模式驗證
啟動redis
在/usr/local/etc/redis/sentinel/server路徑下執行:
docker-compose up
啟動sentinel
在/usr/local/etc/redis/sentinel/sentinel路徑下執行:
docker-compose up
觀察sentinel的日志
可以看到三個sentinel節點都監視了master節點,這個時候我們可以把maste節點停下來試一下
可以看到日志輸出,有兩個sentinel節點認為master節點主觀下線之后,有一個節點認為master節點客觀下線
然后開始開始投票選舉領頭sentinel
由於這段內容涉及的ip地址太多,所以很多地方給模糊處理了一下,請諒解~
從上面截圖中可以看出,領頭sentinel重新選出了一個master節點,127.0.0.1:6380,然后發送命令給其他的從服務節點,讓他們成為新主服務節點的從服務節點,這就是哨兵模式高可用的原因之一,當redis-master掛掉以后,sentinel會選出一個領頭sentinel,這個領頭sentinel又會繼續從從服務器列表中選出一個master節點,再通知其余的從節點成為這個主節點的從節點,這就完成了主節點切換的工作。
參考文章
Sentinel
The Secret Lives of Data
使用 Docker 配置 Redis 哨兵
Markdown小技巧之空格輸入