Redis分片集群
概述
Redis 分片集群(Redis Cluster)通过数据分片实现水平扩展,支持高可用和故障自动转移。本文档涵盖三主三从集群的部署、缩容、扩容、备份与恢复操作。
核心概念:
- 数据分片:16384 个哈希槽均匀分布在各主节点
- 主从复制:每个主节点至少一个从节点,实现高可用
- 故障转移:主节点故障时从节点自动提升为主节点
- 无中心架构:所有节点均可接收请求并路由到正确节点
适用场景:
- 大规模数据存储需要水平扩展
- 高并发读写需要负载均衡
- 需要自动故障转移的高可用架构
部署
1. 创建 Docker Compose 编排文件
docker-compose.yaml(三主三从配置):
services:
redis-node-1:
image: docker.io/redis:5.0.5
container_name: redis-node-1
command: redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-migration-barrier 1
--cluster-require-full-coverage no
--appendonly yes
--port 17001
--requirepass moxigame
--masterauth moxigame
network_mode: host
volumes:
- ./data/node-1:/data
restart: unless-stopped
redis-node-2:
image: docker.io/redis:5.0.5
container_name: redis-node-2
command: redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-migration-barrier 1
--cluster-require-full-coverage no
--appendonly yes
--port 17002
--requirepass moxigame
--masterauth moxigame
network_mode: host
volumes:
- ./data/node-2:/data
restart: unless-stopped
redis-node-3:
image: docker.io/redis:5.0.5
container_name: redis-node-3
command: redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-migration-barrier 1
--cluster-require-full-coverage no
--appendonly yes
--port 17003
--requirepass moxigame
--masterauth moxigame
network_mode: host
volumes:
- ./data/node-3:/data
restart: unless-stopped
redis-node-4:
image: docker.io/redis:5.0.5
container_name: redis-node-4
command: redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-migration-barrier 1
--cluster-require-full-coverage no
--appendonly yes
--port 17004
--requirepass moxigame
--masterauth moxigame
network_mode: host
volumes:
- ./data/node-4:/data
restart: unless-stopped
redis-node-5:
image: docker.io/redis:5.0.5
container_name: redis-node-5
command: redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-migration-barrier 1
--cluster-require-full-coverage no
--appendonly yes
--port 17005
--requirepass moxigame
--masterauth moxigame
network_mode: host
volumes:
- ./data/node-5:/data
restart: unless-stopped
redis-node-6:
image: docker.io/redis:5.0.5
container_name: redis-node-6
command: redis-server
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-migration-barrier 1
--cluster-require-full-coverage no
--appendonly yes
--port 17006
--requirepass moxigame
--masterauth moxigame
network_mode: host
volumes:
- ./data/node-6:/data
restart: unless-stopped2. 启动服务
docker compose up -d查看启动状态:
docker compose ps3. 创建集群
redis-cli -a moxigame --cluster create \
10.0.1.247:17001 10.0.1.247:17002 10.0.1.247:17003 \
10.0.1.247:17004 10.0.1.247:17005 10.0.1.247:17006 \
--cluster-replicas 1 --cluster-yes参数说明:
--cluster-replicas 1:每个主节点分配 1 个从节点--cluster-yes:自动确认集群创建-a moxigame:认证密码
4. 验证集群状态
redis-cli -a moxigame -c -p 17001 cluster info
redis-cli -a moxigame -c -p 17001 cluster nodes缩容
缩容从节点
# 1. 查看节点列表,获取要删除的从节点 ID
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17004
# 2. 删除从节点
redis-cli -a moxigame --cluster del-node 10.0.1.247:17001 <从节点ID>
# 3. 确认已删除
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17004
# 4. 检查集群状态
redis-cli -a moxigame -c -p 17001 cluster info | grep cluster_state
# 输出 cluster_state:ok缩容主节点
主节点缩容需先迁移哈希槽,再删除节点。
# 1. 查看要删除的主节点信息
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17003
# 记录:节点 ID(如 04d6252fe6ca1f48b3a4cd7ca37baa1c817a8786)
# 记录:持有的哈希槽范围(如 10923-16383,共 5461 个槽)
# 2. 进入任意主节点容器
docker exec -it redis-node-1 bash
# 3. 执行槽位迁移
redis-cli -a moxigame --cluster reshard 10.0.1.247:17001交互步骤:
| 提示 | 输入 |
|---|---|
| How many slots do you want to move? | 5461(源节点持有的槽数) |
| What is the receiving node ID? | 目标节点 ID(如 17001 的 ID) |
| Source node #1? | 源节点 ID(17003 的 ID) |
| Source node #2? | done |
| Do you want to proceed? | yes |
# 4. 迁移完成验证:确认源节点已无槽位
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17003
# 5. 删除主节点
redis-cli -a moxigame --cluster del-node 10.0.1.247:17001 <主节点ID>
# 6. 最终验证
redis-cli -a moxigame -c -p 17001 cluster nodes | grep -E "17003|17006"
redis-cli -a moxigame -c -p 17001 cluster info | grep cluster_slots_assigned
# 输出 cluster_slots_assigned:16384 表示槽位完整
# 7. 测试数据读写
redis-cli -a moxigame -c -p 17001 set test_reshard "success"
redis-cli -a moxigame -c -p 17001 get test_reshard扩容
添加新节点
# 1. 新节点已启动(如 17004),加入集群
redis-cli -a moxigame --cluster add-node 10.0.1.247:17004 10.0.1.247:17001
# 2. 查看新节点状态(默认为主节点)
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17004
# 3. 将新节点设置为从节点(如需要)
redis-cli -a moxigame -c -p 17001 cluster replicate <主节点ID>
# 4. 为新节点分配哈希槽(reshard)
redis-cli -a moxigame --cluster reshard 10.0.1.247:17001迁移槽位到新节点
# 示例:从所有现有主节点迁移槽位到新节点
redis-cli -a moxigame --cluster rebalance 10.0.1.247:17001 \
--cluster-threshold 1 --cluster-weight 10.0.1.247:17004=1备份
方法一:RDB 文件备份(推荐)
# 1. 进入节点容器
docker exec -it redis-node-1 bash
# 2. 触发 RDB 持久化
redis-cli -a moxigame -c -p 17001 save
# 3. 退出容器,备份数据目录
docker compose down
tar -czf redis_backup_$(date +%Y%m%d).tar.gz ./data/
docker compose up -d方法二:持续备份
# 使用脚本定时备份
cat > backup_redis.sh <<'EOF'
#!/bin/bash
BACKUP_DIR=/backup/redis
DATE=$(date +%Y%m%d_%H%M%S)
docker exec redis-node-1 redis-cli -a moxigame save
tar -czf $BACKUP_DIR/redis_data_$DATE.tar.gz ./data/
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
EOF
chmod +x backup_redis.sh
# 添加到 crontab(每天凌晨 2 点执行)
0 2 * * * /path/to/backup_redis.sh恢复
RDB 恢复
# 1. 停止所有节点
docker compose down
# 2. 清空数据目录(或恢复备份文件)
rm -rf ./data/*
# 3. 解压备份文件
tar -xzf redis_backup_20260101.tar.gz -C ./
# 4. 启动服务
docker compose up -d
# 5. 验证数据
redis-cli -a moxigame -c -p 17001 cluster nodes
redis-cli -a moxigame -c -p 17001 get <test_key>完整集群恢复
如果集群元数据丢失,需重新创建集群:
# 1. 停止并清理数据
docker compose down
rm -rf ./data/*
# 2. 恢复 RDB 文件到各节点目录
# (将备份的 RDB 文件放入对应节点目录)
# 3. 启动节点
docker compose up -d
# 4. 重新创建集群
redis-cli -a moxigame --cluster create \
10.0.1.247:17001 10.0.1.247:17002 10.0.1.247:17003 \
10.0.1.247:17004 10.0.1.247:17005 10.0.1.247:17006 \
--cluster-replicas 1 --cluster-yes配置参数说明
| 参数 | 说明 |
|---|---|
cluster-enabled yes |
启用集群模式 |
cluster-config-file nodes.conf |
集群节点配置文件 |
cluster-node-timeout 5000 |
节点超时时间(毫秒) |
cluster-migration-barrier 1 |
从节点迁移最少主节点数量 |
cluster-require-full-coverage no |
部分槽位不可用时仍提供服务 |
appendonly yes |
开启 AOF 持久化 |
requirepass |
客户端连接密码 |
masterauth |
从节点连接主节点密码 |
常用管理命令
| 操作 | 命令 |
|---|---|
| 查看集群信息 | redis-cli -a 密码 -c -p 端口 cluster info |
| 查看节点列表 | redis-cli -a 密码 -c -p 端口 cluster nodes |
| 检查集群状态 | redis-cli -a 密码 --cluster check 地址:端口 |
| 查看哈希槽分配 | redis-cli -a 密码 --cluster info 地址:端口 |
| 查看节点间的槽位 | redis-cli -a 密码 -c -p 端口 cluster slots |
常见问题与注意事项
集群创建失败
- 确认所有节点已正常启动:
docker compose ps - 检查节点间网络是否互通(
network_mode: host需宿主机端口开放) - 确认防火墙放行 17001-17006 端口
- 检查配置文件是否一致(密码、端口)
缩容时提示"Node contains slots"
主节点必须先将所有哈希槽迁移至其他节点,才能执行删除。
扩容节点加入失败
# 清除节点数据重新加入
docker exec -it redis-node-4 rm -rf /data/*
docker compose restart redis-node-4
redis-cli -a moxigame --cluster add-node 10.0.1.247:17004 10.0.1.247:17001集群脑裂或状态不一致
# 检查集群状态
redis-cli -a moxigame --cluster check 10.0.1.247:17001
# 修复集群
redis-cli -a moxigame --cluster fix 10.0.1.247:17001密码配置不一致
所有节点 requirepass 和 masterauth 需保持一致,否则主从复制会失败。
备份恢复后集群状态异常
恢复 RDB 后,节点可能包含不一致的集群元数据,需重新创建集群:
# 清除集群元数据
rm -f ./data/*/nodes.conf
docker compose restart
# 重新创建集群
redis-cli -a moxigame --cluster create ...