008.Redis Cluster集群架构实践
文章目录
- Cluster模式实战
- 环境准备
- 时钟服务
- 变量准备
- 互信配置
- Redis安装前置优化
- 编译安装
- Redis服务单元
- Redis 成员节点配置
- 其他节点配置
- Redis服务启动
- 确认服务
- 组建集群
- 确认验证
- 集群管理
- 查看集群
- 数据操作
- 故障模拟
Cluster模式实战
环境准备
- 安全预设
根据实际情况,关闭防火墙和SELinux。
[root@redis01 ~]# systemctl disable firewalld --now
[root@redis01 ~]# sed -i 's/=enforcing/=disabled/g' /etc/selinux/config
注意:以上操作需要在所有节点上执行。
- 节点规划
角色 | 主机名 | IP地址 | 槽位规划 |
---|---|---|---|
Redis Master | redis01 | 172.24.8.11 | 0-5460 |
Redis Master | redis02 | 172.24.8.12 | 5461-10922 |
Redis Master | redis03 | 172.24.8.13 | 10923-16383 |
Redis01 的 Slave | redis04 | 172.24.8.14 | —— |
Redis02 的 Slave | redis05 | 172.24.8.15 | —— |
Redis03 的 Slave | redis06 | 172.24.8.16 | —— |
- 配置主机名
建议配置内部主机名解析。
[root@redis01 ~]# cat >> /etc/hosts << EOF
172.24.8.11 redis01
172.24.8.12 redis02
172.24.8.13 redis03
172.24.8.14 redis04
172.24.8.15 redis05
172.24.8.16 redis06
EOF
时钟服务
主从架构建议保证时钟服务正确,具体时钟配置参考:NTP服务器
001.Chrony时间服务器
- ntpd服务查看
[root@redis01 ~]# ntpq -npremote refid st t when poll reach delay offset jitter
==============================================================================
*116.62.13.223 100.100.61.92 2 u 28 64 377 34.750 24.098 4.261
+203.107.6.88 100.107.25.114 2 u 13 64 377 47.745 18.287 8.121
- chrony服务查看
[root@redis01 ~]# chronyc sources -v
变量准备
为实现自动化部署,自动化分发相关文件,提前定义相关主机名、IP组、变量等。
[root@redis01 ~]# vim redisnodes.sh #确认相关主机名和IP
#!/bin/bash
#***************************************************************#
# ScriptName: redisnodes.sh
# Author: xhy
# Create Date: 2025-02-22 01:44
# Modify Author: xhy
# Modify Date: 2025-02-22 01:44
# Version: v1
#***************************************************************## 集群 REDIS 机器 IP 数组
export REDIS_IPS=(172.24.8.11 172.24.8.12 172.24.8.13)# 集群 REDIS IP 对应的主机名数组
export REDIS_NAMES=(redis01 redis02 redis03)# 集群 CLUSTER 机器 IP 数组
export ALL_IPS=(172.24.8.11 172.24.8.12 172.24.8.13 172.24.8.14 172.24.8.15 172.24.8.16)# 集群 CLUSTER IP 对应的主机名数组
export ALL_NAMES=(redis01 redis02 redis03 redis04 redis05 redis06)
互信配置
为了方便远程分发文件和执行命令,本方案配置 redis01 节点到其它节点的 ssh信任关系,即免秘钥管理所有其他节点。
[root@redis01 ~]# source redisnodes.sh #载入变量[root@redis01 ~]# wget http://down.linuxsb.com/myshell/mkpublickey.sh
[root@redis01 ~]# vi mkpublickey.sh #确认IP[root@redis01 ~]# bash mkpublickey.sh redhat123
提示:如上仅需在 redis01 节点上操作。
Redis安装前置优化
[root@redis01 ~]# chmod +x *.sh
[root@redis01 ~]# source redisnodes.sh
[root@redis01 ~]# for all_ip in ${ALL_IPS[@]}doecho -e "\n\n\033[33m[INFO] >>> ${all_ip}...\033[0m"sleep 2scp -rp /etc/hosts root@${all_ip}:/etc/hostsssh root@${all_ip} "echo 'vm.overcommit_memory=1' > /etc/sysctl.d/redis-sysctl.conf"ssh root@${all_ip} "sysctl -p /etc/sysctl.d/redis-sysctl.conf"ssh root@${all_ip} "echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local"done
提示:如上仅需在 redis01 上操作。
编译安装
建议使用编译安装。
[root@redis01 ~]# source redisnodes.sh
[root@redis01 ~]# for all_ip in ${ALL_IPS[@]}doecho -e "\n\n\033[33m[INFO] >>> ${all_ip}...\033[0m"sleep 2scp -rp /etc/hosts root@${all_ip}:/etc/hostsssh root@${all_ip} "mkdir -p /tmp/redis-tmp /etc/redis/ /var/log/redis/"ssh root@${all_ip} << EOFREIDS_VER=8.0.3DOWNLOAD_URL="https://mirrors.huaweicloud.com/redis"curl -L "\${DOWNLOAD_URL}/redis-\${REIDS_VER}.tar.gz" -o "/tmp/redis-\${REIDS_VER}.tar.gz"tar xzvf "/tmp/redis-\${REIDS_VER}.tar.gz" -C /tmp/redis-tmp --strip-components=1 --no-same-ownercd /tmp/redis-tmpmake -j4make install PREFIX=/usr/local/redisecho 'PATH=/usr/local/redis/bin:\$PATH' > /etc/profile.d/redis.shsource /etc/profile.d/redis.shredis-cli -v
EOFdone
提示:所有主从节点都需要安装Redis,如上可实现所有节点循环编译完成安装。
Redis服务单元
通过服务单元的方式管理Redis是更推荐的方式,更符合最佳实践。
[root@redis01 ~]# cat > /usr/lib/systemd/system/redis-server.service <<EOF
[Unit]
Description=Redis Server Manager
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://redis.io/documentation[Service]
ExecStart=/usr/local/redis/bin/redis-server /etc/redis/redis01_6379.conf
ExecStop=/usr/local/redis/bin/redis-cli shutdown
#Restart=on-failure
RestartSec=5
Type=forking[Install]
WantedBy=multi-user.target
EOF[root@redis01 ~]# source redisnodes.sh
[root@redis01 ~]# for redis_ip in ${ALL_IPS[@]}doecho -e "\n\n\033[33m[INFO] >>> ${redis_ip}...\033[0m"sleep 2scp -rp /usr/lib/systemd/system/redis-server.service root@${redis_ip}:/usr/lib/systemd/system/ssh root@${redis_ip} "mkdir -p /run/redis"done
提示:所有主从节点都建议使用服务单元的方式管理。
Redis 成员节点配置
[root@redis01 ~]# mkdir -p /var/lib/redis/redis01/ #创建Redis RDB持久化文件保存路径[root@redis01 ~]# cp /tmp/redis-tmp/redis.conf /etc/redis/redis01_6379.conf[root@redis01 ~]# vim /etc/redis/redis01_6379.conf
#……
# 核心配置项:
bind 0.0.0.0 -::1 # 允许所有IP连接
protected-mode no # 关闭保护模式
port 6379
daemonize yes # 开启后台运行
logfile "/var/log/redis/redis01.log" # log文件存储位置
dir "/var/lib/redis/redis01" # 本地数据库存储目录# 集群核心配置
cluster-enabled yes # 是否以集群模式启动
cluster-config-file nodes-6379.conf # 生成的集群节点配置文件名
cluster-node-timeout 15000 # 集群节点回应最长时间,超过该时间被认为下线
cluster-require-full-coverage no
cluster-replica-validity-factor 0 # 允许故障后立即切换# 安全配置(按需启用)
requirepass "StrongPassword123!" # 基于安全考虑增加验证
#……
其他节点配置
- 配置分发
将服务单元和配置文件分发至所有其他节点。
[root@redis01 ~]# for all_ip in ${ALL_IPS[@]}doecho -e "\n\n\033[33m[INFO] >>> ${all_ip}...\033[0m"sleep 2ssh root@${all_ip} "mkdir -p /var/lib/redis/redis01"scp -rp /etc/redis/redis01_6379.conf root@${all_ip}:/etc/redis/scp -rp /usr/lib/systemd/system/redis-server.service root@${all_ip}:/usr/lib/systemd/system/done
集群节点会在添加集群成员的时候自动配置从节点。
Redis服务启动
所有节点相同配置,然后启动redis服务。
[root@redis01 ~]# for all_ip in ${ALL_IPS[@]}doecho -e "\n\n\033[33m[INFO] >>> ${all_ip}...\033[0m"sleep 5ssh root@${all_ip} "systemctl daemon-reload"ssh root@${all_ip} "systemctl enable redis-server.service --now"ssh root@${all_ip} "systemctl restart redis-server.service"ssh root@${all_ip} "systemctl status redis-server.service"done
确认服务
当所有节点redis服务启动后,查看相关服务以及集群配置文件是否生成一组集群信息。
每个redis信息都不相同,彼此之间没有联通。
[root@redis01 ~]# for all_ip in ${ALL_IPS[@]}doecho -e "\n\n\033[33m[INFO] >>> ${all_ip}...\033[0m"sleep 5ssh root@${all_ip} "systemctl status redis-server.service | grep Active"ssh root@${all_ip} "cat /var/lib/redis/redis01/nodes-6379.conf"done
组建集群
在任何节点可执行组建集群的命令。
[root@redis01 ~]# redis-cli --cluster create \172.24.8.11:6379 \172.24.8.12:6379 \172.24.8.13:6379 \172.24.8.14:6379 \172.24.8.15:6379 \172.24.8.16:6379 \-a StrongPassword123! \--cluster-replicas 1
提示:
–cluster-replicas 1:指定每个主节点的从节点数量
前 N 个节点是主节点:N = 总节点数 / (replicas+1)
后 M 个节点是从节点:M = N * replicas
Redis 会按顺序自动绑定:从节点1 → 主节点1,从节点2 → 主节点2 …
确认验证
查看相关集群信息。
[root@redis01 ~]# redis-cli -h 172.24.8.11 -a StrongPassword123! cluster nodes # 查看节点关系
[root@redis01 ~]# redis-cli -h 172.24.8.11 -a StrongPassword123! cluster slots # 检查槽位分配
集群管理
查看集群
[root@redis06 ~]# redis-cli -a StrongPassword123! -c -h 172.24.8.11
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
172.24.8.11:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:328
cluster_stats_messages_pong_sent:340
cluster_stats_messages_sent:668
cluster_stats_messages_ping_received:335
cluster_stats_messages_pong_received:328
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:668
total_cluster_links_buffer_limit_exceeded:0
数据操作
172.24.8.11:6379> SET user:1001 "Alice" #自动路由到正确节点
-> Redirected to slot [5712] located at 172.24.8.12:6379
OK
172.24.8.12:6379> CLUSTER NODES
6335a2adc42904de1ce32e76c9036059dbfba3fc 172.24.8.12:6379@16379 myself,master - 0 0 2 connected 5461-10922
d454ff1a2b09c212d57b8e6a6d44e36e83abade4 172.24.8.14:6379@16379 slave a24a969f1c04af9a7f41f983db014b736b2dc18c 0 1753366216099 3 connected
6e668b9a4ac3c56a063ad8c393b6713a89e7fdee 172.24.8.15:6379@16379 slave 9d20b8209736ee9b9ac2da2a66071707a4ab2057 0 1753366215092 1 connected
9d20b8209736ee9b9ac2da2a66071707a4ab2057 172.24.8.11:6379@16379 master - 0 1753366214086 1 connected 0-5460
a24a969f1c04af9a7f41f983db014b736b2dc18c 172.24.8.13:6379@16379 master - 0 1753366213081 3 connected 10923-16383
0e6fe4f80bde4180464fc8ef65c7bf81bb792631 172.24.8.16:6379@16379 slave 6335a2adc42904de1ce32e76c9036059dbfba3fc 0 1753366214000 2 connected
故障模拟
- 停止服务
模拟任何一个主节点,如redis01故障。
[root@redis01 ~]# systemctl stop redis-server.service
- 实时监控
实时开启监控,预计30秒后redis01会变成fail。
[root@redis02 ~]# watch -n 1 "redis-cli -h 172.24.8.12 -a StrongPassword123! --no-auth-warning cluster nodes | grep 172.24.8.11"
Every 1.0s: redis-cli -h 172.24.8.12 -a StrongPassword123! --no-auth-warning cluster nodes | grep 172.24.8.11
9d20b8209736ee9b9ac2da2a66071707a4ab2057 172.24.8.11:6379@16379 master,fail - 1753366500843 1753366494804 1 disconnected 0-5460
- 读取数据
读取通过原来redis01写入的数据,依旧能读取到。
[root@redis02 ~]# redis-cli -c -h 172.24.8.12 -a StrongPassword123! --no-auth-warning \GET user:1001
"Alice"
- 恢复服务
恢复服务后观察节点加入。
[root@redis01 ~]# systemctl start redis-server.service[root@redis02 ~]# watch -n 1 "redis-cli -h 172.24.8.12 -a StrongPassword123! --no-auth-warning cluster nodes | grep 172.24.8.11"
Every 1.0s: redis-cli -h 172.24.8.12 -a StrongPassword123! --no-auth-warning cluster nodes | grep 172.24.8.119d20b8209736ee9b9ac2da2a66071707a4ab2057 172.24.8.11:6379@16379 master - 0 1753366765000 1 connected 0-5460