一、环境规划与准备工作
1.1 节点分配
| 服务器 IP | 端口 | 角色 | 备注 |
|---|---|---|---|
| 192.168.101.41 | 6379 | Master 1 | 主节点 |
| 192.168.101.41 | 6380 | Slave 1 | 从节点(作为 .41 主节点的备用) |
| 192.168.101.42 | 6379 | Master 2 | 主节点 |
| 192.168.101.42 | 6380 | Slave 2 | 从节点(作为 .42 主节点的备用) |
| 192.168.101.43 | 6379 | Master 3 | 主节点 |
| 192.168.101.43 | 6380 | Slave 3 | 从节点(作为 .43 主节点的备用) |
注意:Redis 集群的总线通信端口会自动占用 port + 10000,即 16379 和 16380,也需要开放。
1.2 软件环境要求
- 操作系统:CentOS 7.x
- Redis 版本:5.0 或以上(推荐 6.2.x / 7.2.x,内置集群管理工具)
- 网络互通:三台服务器之间需能互相 ping 通,所有端口可互相访问
- 运行账号:
app(如不存在则自动创建)
二、每台服务器统一操作步骤(共三台)
以下操作需在 192.168.101.41、192.168.101.42、192.168.101.43 三台服务器上各自执行一遍。
2.1 创建 app 账号(如已存在可跳过)
# 创建 app 用户组和用户(无登录 shell)
groupadd app
useradd -g app -m -s /sbin/nologin app
# 设置目录权限(后续创建目录后需 chown)2.2 安装 Redis(三台机器)
# 安装依赖
yum install -y gcc gcc-c++ make tcl
# 下载源码
mkdir -p /data/app/src && cd /data/app/src
wget https://download.redis.io/releases/redis-7.2.5.tar.gz
tar -zxvf redis-7.2.5.tar.gz
cd redis-7.2.5
# 编译并指定安装路径
make
make install PREFIX=/data/app/redis
# 将二进制路径加入 PATH(永久生效)
echo 'export PATH=/data/app/redis/bin:$PATH' > /etc/profile.d/redis.sh
source /etc/profile.d/redis.sh
# 验证
/data/app/redis/bin/redis-server --version2.3 创建工作目录(每台机器)
# 创建两个实例的工作目录
mkdir -p /data/redis-cluster/{6379,6380}/data
mkdir -p /data/redis-cluster/{6379,6380}/conf
mkdir -p /data/redis-cluster/{6379,6380}/logs
# 创建集群节点配置文件目录
mkdir -p /var/run/redis-cluster
# 修改目录所有者为 app
chown -R app:app /data/redis-cluster
chown -R app:app /var/run/redis-cluster2.4 生成主节点配置文件(端口 6379)
编辑配置文件:
vi /data/redis-cluster/6379/conf/redis.conf内容如下(以 192.168.101.41 为例,其他机器相同):
# 基础配置
port 6379
bind 0.0.0.0
protected-mode no
daemonize yes
pidfile /var/run/redis-cluster/redis_6379.pid
loglevel notice
logfile /data/redis-cluster/6379/logs/redis.log
# 工作目录和数据目录
dir /data/redis-cluster/6379/data
# ========== 集群配置 ==========
cluster-enabled yes
cluster-config-file /data/redis-cluster/6379/conf/nodes-6379.conf
cluster-node-timeout 5000
# ========== 数据持久化配置 ==========
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump-6379.rdb
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 访问密码
requirepass redispasswd
# 主从同步认证密码
masterauth redispasswd2.5 生成从节点配置文件(端口 6380)
vi /data/redis-cluster/6380/conf/redis.conf内容(将 6379 替换为 6380):
port 6380
bind 0.0.0.0
protected-mode no
daemonize yes
pidfile /var/run/redis-cluster/redis_6380.pid
loglevel notice
logfile /data/redis-cluster/6380/logs/redis.log
dir /data/redis-cluster/6380/data
cluster-enabled yes
cluster-config-file /data/redis-cluster/6380/conf/nodes-6380.conf
cluster-node-timeout 5000
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump-6380.rdb
appendonly yes
appendfilename "appendonly-6380.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
requirepass redispasswd
masterauth redispasswd2.6 配置防火墙(三台机器)
# 开放 Redis 端口
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --permanent --add-port=6380/tcp
# 开放集群总线端口
firewall-cmd --permanent --add-port=16379/tcp
firewall-cmd --permanent --add-port=16380/tcp
# 重载防火墙
firewall-cmd --reload
# 验证
firewall-cmd --list-ports若生产环境不方便关闭 SELinux,可临时关闭:
setenforce 0
sed -i 's/=enforcing/=disabled/g' /etc/selinux/config2.7 配置 systemd 开机自启(使用 app 账号):
# 主节点 service
cat > /etc/systemd/system/redis-6379.service << EOF
[Unit]
Description=Redis Server 6379
After=network.target
[Service]
Type=forking
User=app
Group=app
ExecStart=/data/app/redis/bin/redis-server /data/redis-cluster/6379/conf/redis.conf
ExecStop=/data/app/redis/bin/redis-cli -p 6379 -a 'redispasswd' shutdown
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 从节点 service(端口改为 6380)
cat > /etc/systemd/system/redis-6380.service << EOF
[Unit]
Description=Redis Server 6380
After=network.target
[Service]
Type=forking
User=app
Group=app
ExecStart=/data/app/redis/bin/redis-server /data/redis-cluster/6380/conf/redis.conf
ExecStop=/data/app/redis/bin/redis-cli -p 6380 -a 'redispasswd' shutdown
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 启用
systemctl enable redis-6379 redis-6380
# 验证
ps aux | grep redis-server
netstat -tuln | grep -E '6379|6380'三、创建 Redis 集群(只需在一台机器执行)
当 三台服务器上的 6 个 Redis 实例全部启动后,在任意一台有 redis-cli 的机器上执行:
redis-cli -a 'redispasswd' --cluster create \
192.168.101.41:6379 \
192.168.101.42:6379 \
192.168.101.43:6379 \
192.168.101.41:6380 \
192.168.101.42:6380 \
192.168.101.43:6380 \
--cluster-replicas 1系统会输出槽位分配,输入 yes 确认。看到以下输出即成功:
text
[OK] All 16384 slots covered.四、数据持久化配置详解
4.1 双重持久化策略:AOF + RDB
- AOF 每秒同步:
appendfsync everysec最多丢失 1 秒数据。 - 重启优先使用 AOF 恢复,数据更完整。
- AOF 重写:自动压缩,避免文件过大。
4.2 验证持久化是否生效
# 写入测试数据
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' set test_key "test_value"
# 检查持久化文件
ls -la /data/redis-cluster/6379/data/ # 应有 .rdb 和 .aof
# 手动触发 AOF 重写
redis-cli -p 6379 -a 'redispasswd' BGREWRITEAOF五、重启与数据恢复验证方案
5.1 重启单个 Redis 实例
# 写入测试数据
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' set user:1001 "test1001"
# 停止实例(使用 app 账号)
su - app -s /bin/bash -c "/data/app/redis/bin/redis-cli -h 192.168.101.41 -p 6379 -a 'redispasswd' shutdown"
# 重启
service redis-6379 restart
# 验证数据
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' get user:1001 # 应返回 "test1001"5.2 模拟实例宕机(kill -9)
# 写入 100 条数据
for i in {1..100}; do
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' --no-auth-warning set "test:key:$i" "value_$i" 2>/dev/null
printf "Progress: %3d/100\r" $i
done
echo -e "\n✅ 写入完成"
# 强制杀死进程(查找 app 用户的进程)
systemctl stop redis-6379 redis-6380
# 重启
systemctl restart redis-6379 redis-6380
# 查询所有节点的key总数
echo "=== 分别查询每个节点 ==="
for node in 192.168.101.41 192.168.101.42 192.168.101.43; do
count=$(redis-cli -h $node -p 6379 -a 'redispasswd' --no-auth-warning keys "test:key:*" 2>/dev/null | wc -l)
echo "$node:6379 - $count 条"
done
echo ""
echo "总计:32 + 30 + 38 = 100 条 ✅"5.3 整机重启(模拟断电/维护)
前提:已配置 systemd 开机自启。
# 重启前写入标记
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' set after_reboot_test "data_before_reboot"
# 重启服务器
reboot
# 重启后检查
systemctl status redis-6379 redis-6380
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' cluster info | grep cluster_state # 应为 ok
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' get after_reboot_test # 应返回原值5.4 主节点故障自动转移(高可用)
# 写入 1000 条数据
for i in {1..1000}; do
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd' set hatest:$i "payload_$i"
done
# 关闭主节点 192.168.101.41:6379
redis-cli -h 192.168.101.41 -p 6379 -a 'redispasswd' shutdown
# 等待 15 秒,查看哪个从节点被提升
redis-cli -h 192.168.101.42 -p 6379 -a 'redispasswd' cluster nodes
# 数据验证(连接新主节点)
redis-cli -c -h 192.168.101.42 -p 6380 -a 'redispasswd' get hatest:500六、常用管理与监控命令
6.1 集群状态检查
redis-cli -c -h 192.168.101.41 -p 6379 -a 'redispasswd'
> cluster info
> cluster nodes
> cluster slots6.2 单节点管理
# 停止节点(使用 app 账号)
su -s /bin/bash -c "/data/app/redis/bin/redis-cli -h 192.168.101.41 -p 6379 -a 'redispasswd' shutdown" app
# 启动节点
su -s /bin/bash -c "/data/app/redis/bin/redis-server /data/redis-cluster/6379/conf/redis.conf" app
# 查看日志
tail -f /data/redis-cluster/6379/logs/redis.log6.3 数据持久化验证
ls -lh /data/redis-cluster/*/data/*.aof
redis-cli -h 192.168.101.41 -p 6379 -a 'redispasswd' BGSAVE
redis-cli -h 192.168.101.41 -p 6379 -a 'redispasswd' BGREWRITEAOF七、故障排查清单
🔴 问题1:重启后节点未自动加入集群
- 确保
cluster-config-file目录可写且属主为app - 检查网络:
telnet 192.168.101.42 6379 - 手动握手:
redis-cli -h 192.168.101.42 -p 6379 -a 'redispasswd' CLUSTER MEET 192.168.101.41 6379
🔴 问题2:数据恢复不完整
- 检查
appendonly yes是否配置 - 修复 AOF:
redis-check-aof --fix /path/to/appendonly.aof
🔴 问题3:集群状态为 FAIL
- 检查所有节点是否运行:
ps aux | grep redis-server - 检查防火墙端口(包括 16379、16380)
- 等待足够节点恢复后集群自动恢复
🔴 问题4:权限不足导致启动失败
- 检查目录权限:
ls -la /data/redis-cluster(应为app:app) - 检查 PID 目录权限:
ls -la /var/run/redis-cluster - 使用
su命令切换用户启动,或通过 systemd(已配置User=app)启动
八、Redis 集群版本升级方案(不停服滚动升级)
8.1 升级前准备
8.1.1 环境检查
# 记录当前版本(三台机器)
/data/app/redis/bin/redis-server --version
# 记录集群状态
redis-cli -a 'redispasswd' --cluster check 192.168.101.41:6379
# 备份当前二进制及配置文件(三台机器)
tar -czf /data/backup/redis-$(date +%Y%m%d)-bin.tar.gz /data/app/redis/
cp -r /data/redis-cluster /data/backup/redis-cluster-$(date +%Y%m%d)8.1.2 下载目标版本(以升级到 7.4.0 为例)
cd /data/app/src
wget https://download.redis.io/releases/redis-7.4.0.tar.gz
tar -zxvf redis-7.4.0.tar.gz
cd redis-7.4.0
# 编译
make8.2.1 升级从节点(以 192.168.101.41:6380 为例)
# 1. 确认当前角色为从节点
redis-cli -h 192.168.101.41 -p 6380 -a 'redispasswd' role
# 预期输出中 "role" 为 "slave"
# 2. 停止旧版本实例
systemctl stop redis-6380
# 3. 替换二进制文件
mv /data/app/redis/bin /data/app/redis/bin.bak-$(date +%Y%m%d)
mkdir -p /data/app/redis/bin
cp /data/app/src/redis-7.4.0/src/{redis-server,redis-cli,redis-check-aof,redis-check-rdb,redis-sentinel} /data/app/redis/bin/
# 4. 验证新版本
/data/app/redis/bin/redis-server --version
# 5. 启动新版本实例
systemctl start redis-6380
# 6. 验证同步状态
redis-cli -h 192.168.101.41 -p 6380 -a 'redispasswd' info replication | grep -E "role|master_link_status"8.2.2 执行主从切换(可选,如需升级主节点)
# 手动触发故障转移,将从节点提升为主节点
redis-cli -h 192.168.101.41 -p 6380 -a 'redispasswd' cluster failover
# 等待切换完成(约 5-10 秒)
sleep 10
# 验证新主节点
redis-cli -h 192.168.101.41 -p 6380 -a 'redispasswd' role
# 预期 "role" 变为 "master"8.2.3 升级原主节点(现在已降级为从节点)
# 此时原主节点 6379 已变为从节点,重复 8.2.1 步骤升级
systemctl stop redis-6379
# ... 替换二进制 ...
systemctl start redis-63798.2.4 依次升级其他机器
| 机器 | 升级顺序建议 |
|---|---|
| 192.168.101.41 | 6380(从)→ 6379(原主) |
| 192.168.101.42 | 6380(从)→ 6379(原主) |
| 192.168.101.43 | 6380(从)→ 6379(原主) |
8.3 升级后验证
8.3.1 集群健康检查
# 检查集群状态
redis-cli -a 'redispasswd' --cluster check 192.168.101.41:6379
# 验证所有节点版本
for port in 6379 6380; do
echo "=== 192.168.101.41:$port ==="
redis-cli -h 192.168.101.41 -p $port -a 'redispasswd' info server | grep redis_version
done8.3.2 数据完整性验证
# 查询所有节点的key总数
echo "=== 分别查询每个节点 ==="
for node in 192.168.101.41 192.168.101.42 192.168.101.43; do
count=$(redis-cli -h $node -p 6379 -a 'redispasswd' --no-auth-warning keys "test:key:*" 2>/dev/null | wc -l)
echo "$node:6379 - $count 条"
done
echo ""
echo "总计:32 + 30 + 38 = 100 条 ✅"8.4 回滚方案(升级失败时)
8.4.1 快速回滚(保留原二进制备份)
# 停止问题实例
systemctl stop redis-6379
# 恢复旧版本二进制
rm -rf /data/app/redis/bin
mv /data/app/redis/bin.bak-YYYYMMDD /data/app/redis/bin
# 重启实例
systemctl start redis-63798.4.2 全量回滚(保留配置和数据)
# 停止所有实例
systemctl stop redis-6379 redis-6380
# 恢复完整环境(从备份)
rm -rf /data/app/redis
tar -xzf /data/backup/redis-YYYYMMDD-bin.tar.gz -C /
# 重启所有实例
systemctl start redis-6379 redis-63808.5 升级注意事项
| 风险点 | 应对措施 |
|---|---|
| 客户端协议不兼容 | 升级前确认业务使用的 Redis 命令未被废弃或变更 |
| RDB/AOF 加载失败 | 升级前在测试环境验证,生产环境先升级单节点观察 |
| 集群脑裂 | 滚动升级期间避免同时重启多个主节点 |
| 密码/ACL 变更 | 新版本可能引入 ACL 规则变化,检查 requirepass 与 masterauth |
| 模块兼容性 | 如使用了 Redis Module(如 RediSearch),需同步升级模块 |
8.6 升级检查清单
- [ ] 已记录当前版本与集群状态
- [ ] 已完成二进制及配置文件备份
- [ ] 已在测试环境完成版本兼容性验证
- [ ] 已通知业务方升级时间窗口
- [ ] 已准备回滚脚本与备份文件
- [ ] 滚动升级过程中每完成一个节点均验证同步状态
- [ ] 升级后完成集群健康检查与数据抽样验证
- [ ] 已更新运维文档中的版本信息
评论 (0)