Redis高可用集羣Docker部署方案
一、架構設計
集羣拓撲結構
本方案採用3主3從的標準Redis Cluster架構,確保高可用性和數據安全 。
|
節點角色
|
容器名稱
|
數據端口
|
集羣總線端口
|
Docker內部IP |
|
Master1
|
redis-7001
|
7001
|
17001
|
172.20.0.111 |
|
Master2
|
redis-7002
|
7002
|
17002
|
172.20.0.112
|
|
Master3
|
redis-7003
|
7003
|
17003
|
172.20.0.113
|
|
Slave1
|
redis-7004
|
7004
|
17004
|
172.20.0.114
|
|
Slave2
|
redis-7005
|
7005
|
17005
|
172.20.0.115
|
|
Slave3
|
redis-7006
|
7006
|
17006
|
172.20.0.116
|
總線端口(原端口號+10000)用於節點間通信、故障檢測和故障轉移,必須開放
二、創建目錄和配置文件
首先,創建一個清晰的項目結構
mkdir -p redis-cluster/{7001..7006}/data
cd redis-cluster
1.創建配置模板 (redis-cluster.tmpl)
這個模板文件定義了集羣和持久化的核心參數,${PORT}會在啓動時被實際端口號替換。
vim redis-cluster.tmpl
# 基礎配置
port ${PORT}
bind 0.0.0.0
daemonize no
protected-mode no
timeout 300
tcp-keepalive 60
# 集羣配置
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-replica-validity-factor 10
cluster-migration-barrier 1
# 持久化配置 (生產環境關鍵)
appendonly yes
appendfilename "appendonly-${PORT}.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump-${PORT}.rdb
# 內存管理
maxmemory 2gb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# 安全配置
requirepass 123456
masterauth 123456
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
# 集羣網絡公告 (多主機部署時必須配置)
cluster-announce-ip ${NODE_IP}
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
# 日誌配置
loglevel notice
logfile "/data/redis.log"
databases 1
# 性能調優
hz 10
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
repl-disable-tcp-nodelay no
repl-backlog-size 64mb
2.生成節點配置文件
運行以下腳本,為6個節點(端口7001-7006)生成具體的配置文件
vim generate-config.sh << EOF
#!/bin/bash
echo "開始生成Redis節點配置文件(使用sed方法)..."
for port in 7001 7002 7003 7004 7005 7006; do
mkdir -p "$port/conf"
# 動態計算IP地址,例如7001對應172.20.0.111
node_ip="172.20.0.1$((${port: -1} + 10))"
# 使用sed替換模板中的佔位符
sed -e "s/\${PORT}/$port/g" \
-e "s/\${NODE_IP}/$node_ip/g" \
redis-cluster.tmpl > "$port/conf/redis.conf"
if [ $? -eq 0 ]; then
echo "✓ 節點 $port 配置文件生成成功"
else
echo "✗ 節點 $port 配置文件生成失敗"
exit 1
fi
done
echo "所有節點配置文件已生成完畢!"
執行腳本
chmod +x generate-config.sh
./generate-config.sh
3.創建 docker-compose.yml
這個文件定義了6個服務(3主3從),使用了配置文件和自定義網絡
cat > docker-compose.yml << EOF
version: '3.8'
services:
redis-7001:
image: redis:7.2-alpine
container_name: redis-7001
hostname: redis-7001
ports:
- "7001:7001"
- "17001:17001" # 集羣總線端口
volumes:
- ./7001/conf/redis.conf:/etc/redis/redis.conf
- ./7001/data:/data
command: "redis-server /etc/redis/redis.conf --port 7001"
networks:
redis-cluster-net:
ipv4_address: 172.20.0.111
healthcheck:
test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
interval: 5s
timeout: 2s
retries: 3
redis-7002:
image: redis:7.2-alpine
container_name: redis-7002
hostname: redis-7002
ports:
- "7002:7002"
- "17002:17002"
volumes:
- ./7002/conf/redis.conf:/etc/redis/redis.conf
- ./7002/data:/data
command: "redis-server /etc/redis/redis.conf --port 7002"
networks:
redis-cluster-net:
ipv4_address: 172.20.0.112
healthcheck:
test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
interval: 5s
timeout: 2s
retries: 3
redis-7003:
image: redis:7.2-alpine
container_name: redis-7003
hostname: redis-7003
ports:
- "7003:7003"
- "17003:17003"
volumes:
- ./7003/conf/redis.conf:/etc/redis/redis.conf
- ./7003/data:/data
command: "redis-server /etc/redis/redis.conf --port 7003"
networks:
redis-cluster-net:
ipv4_address: 172.20.0.113
healthcheck:
test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
interval: 5s
timeout: 2s
retries: 3
redis-7004:
image: redis:7.2-alpine
container_name: redis-7004
hostname: redis-7004
ports:
- "7004:7004"
- "17004:17004"
volumes:
- ./7004/conf/redis.conf:/etc/redis/redis.conf
- ./7004/data:/data
command: "redis-server /etc/redis/redis.conf --port 7004"
networks:
redis-cluster-net:
ipv4_address: 172.20.0.114
healthcheck:
test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
interval: 5s
timeout: 2s
retries: 3
redis-7005:
image: redis:7.2-alpine
container_name: redis-7005
hostname: redis-7005
ports:
- "7005:7005"
- "17005:17005"
volumes:
- ./7005/conf/redis.conf:/etc/redis/redis.conf
- ./7005/data:/data
command: "redis-server /etc/redis/redis.conf --port 7005"
networks:
redis-cluster-net:
ipv4_address: 172.20.0.115
healthcheck:
test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
interval: 5s
timeout: 2s
retries: 3
redis-7006:
image: redis:7.2-alpine
container_name: redis-7006
hostname: redis-7006
ports:
- "7006:7006"
- "17006:17006"
volumes:
- ./7006/conf/redis.conf:/etc/redis/redis.conf
- ./7006/data:/data
command: "redis-server /etc/redis/redis.conf --port 7006"
networks:
redis-cluster-net:
ipv4_address: 172.20.0.116
healthcheck:
test: ["CMD", "redis-cli", "-a", "your_strong_password_here", "ping"]
interval: 5s
timeout: 2s
retries: 3
networks:
redis-cluster-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
EOF
三、部署和初始化步驟
1.啓動所有節點
docker-compose up -d
2.等待健康檢查通過,確認所有容器狀態為 healthy:
docker-compose ps
3.初始化Redis集羣
docker exec -it redis-7001 redis-cli -a 123456 --cluster create \
172.20.0.111:7001 172.20.0.112:7002 172.20.0.113:7003 \
172.20.0.114:7004 172.20.0.115:7005 172.20.0.116:7006 \
--cluster-replicas 1
執行後,腳本會提示主從分配方案,輸入 yes確認即可。
4.驗證集羣狀態
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster info
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster nodes
四、集羣驗證與監控
1. 健康檢查腳本
cat > health-check.sh << EOF
#!/bin/bash
# health-check.sh
echo "=== Redis集羣健康檢查 ==="
# 檢查集羣狀態
echo "1. 集羣狀態:"
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster info | grep cluster_state
# 檢查節點數量
echo -e "\n2. 節點列表:"
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster nodes | wc -l
# 檢查槽分配
echo -e "\n3. 槽分配情況:"
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster slots | head -10
# 測試讀寫
echo -e "\n4. 讀寫測試:"
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c set test_health "OK"
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c get test_health
echo -e "\n=== 健康檢查完成 ==="
EOF
執行腳本
chmod +x health-check.sh
sh health-check.sh
五、運維管理命令
1. 常用運維操作
# 查看集羣狀態
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster info
# 查看節點詳細信息
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster nodes
# 檢查槽分配
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c cluster slots
# 測試數據分佈
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c set key1 "value1"
# 查看內存使用情況
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 info memory | grep used_memory_human
# 查看連接數
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 info clients | grep connected_clients
2. 故障轉移測試
# 手動觸發故障轉移(將7004提升為主節點)
docker exec -it redis-7004 redis-cli -p 7001 -a 123456 cluster failover
六、安全加固建議
1. 生產環境安全措施
# 1. 使用強密碼替換默認密碼
# 在配置文件中使用強密碼(建議16位以上,包含大小寫字母、數字、特殊字符)
# 2. 網絡隔離
# - 使用內部Docker網絡,不暴露端口到公網
# - 配置防火牆規則,只允許應用服務器訪問
# 3. 禁用危險命令
# 在配置文件中添加:
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
# 4. 定期輪換密碼
# 定期更新requirepass和masterauth密碼
七、故障排查指南
1. 常見問題解決
# 1. 節點無法加入集羣
# 檢查防火牆和網絡連通性
docker exec -it redis-7001 ping 172.20.0.112
# 2. 集羣狀態異常
# 檢查節點間的網絡連接
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 -c --cluster check 172.20.0.111:7001
# 3. 內存不足
# 監控內存使用,適時清理數據或擴容
docker exec -it redis-7001 redis-cli -p 7001 -a 123456 info memory
# 4. 查看日誌排查問題
tail -f ./7001/logs/redis.log
八、性能優化建議
- 內存優化:根據業務需求調整
maxmemory-policy - 持久化優化:平衡AOF頻率與性能要求
- 網絡優化:確保節點間網絡延遲低於
cluster-node-timeout的1/3 - 監控告警:設置集羣狀態、內存使用、連接數等監控指標
此方案提供了生產環境Redis集羣的完整部署和運維指南,具備高可用、高性能、易維護的特點