Redis 三大核心模式(主从复制 / 哨兵 / 集群):完整部署与问题解析
目录
一、Redis 三大模式核心差异总览
二、主从复制:高可用的基石
2.1 核心原理(你实操中需理解的流程)
2.2 完整部署步骤(含你的实操 IP 示例)
环境准备
部署命令(关键步骤)
2.3 常见问题:PID 文件残留(你遇到的 “进程已运行” 错误)
问题现象
原因分析(核心!)
解决步骤
三、哨兵模式:主从集群的 “故障管家”
3.1 核心原理(你必须理解的 3 个阶段)
3.2 完整部署步骤(基于已有主从集群)
环境准备
部署命令(关键步骤)
3.3 常见问题:哨兵端口被占用(你遇到的 “Address already in use”)
问题现象
原因分析
解决步骤
四、集群模式:海量数据的解决方案
4.1 核心原理(你实操中遇到的 “重定向” 本质)
4.2 完整部署步骤(单虚拟机模拟 6 节点,你实操的场景)
环境准备
部署命令(关键步骤,含你遇到的 6001 端口问题解决)
常见错误
一、Redis 三大模式核心差异总览
先明确三者的定位与适用场景,避免混淆。三者并非互斥,而是 “基础→增强→扩展” 的递进关系(主从是基础,哨兵在主从之上实现高可用,集群解决海量数据存储)。
对比维度 | 主从复制(Master-Slave) | 哨兵模式(Sentinel) | 集群模式(Cluster) |
---|---|---|---|
核心目标 | 数据备份、读写分离 | 主从集群的自动故障转移(高可用) | 海量数据分片存储 + 自带高可用 |
数据存储 | 全量复制(所有节点存完整数据) | 全量复制(依赖主从架构) | 分片存储(16384 哈希槽分配到不同主节点) |
节点角色 | 1 主 N 从(从节点只读) | 主从节点 + 哨兵节点(监控决策) | 3 主 3 从(主节点分片,从节点备份) |
故障恢复 | 手动切换主节点 | 自动选举新主节点(需 ≥3 个哨兵) | 自动故障转移(主节点宕机,从节点上位) |
适用场景 | 小规模数据、读多写少(如博客评论) | 小规模数据 + 需高可用(如电商购物车) | 大规模数据(超 10GB)、高并发(如订单) |
关键缺陷 | 无自动故障转移、写操作无负载均衡 | 存储能力受单机限制、写操作无负载均衡 | 部署复杂度高、不支持跨槽事务 |
二、主从复制:高可用的基石
主从复制是 Redis 高可用的基础,通过 “主节点写、从节点读” 实现读写分离,同时完成数据备份。
2.1 核心原理(你实操中需理解的流程)
- 初始化同步:从节点启动后,向主节点发送
SYNC
命令,主节点触发bgsave
生成 RDB 快照,同时缓存快照生成后的写命令。 - 数据传输:主节点将 RDB 快照发送给从节点,从节点加载 RDB 到内存;之后主节点将缓存的写命令同步给从节点,从节点执行命令完成数据对齐。
- 增量同步:后续主节点每执行一次写命令,都会通过 “复制积压缓冲区” 将命令同步给从节点,保证主从数据实时一致。
2.2 完整部署步骤(含你的实操 IP 示例)
环境准备
节点角色 | IP 地址 | 端口 | 核心操作 |
---|---|---|---|
Master | 192.168.10.23 | 6379 | 开启写权限,允许从节点连接 |
Slave1 | 192.168.10.14 | 6379 | 配置 replicaof 指向主节点 |
Slave2 | 192.168.10.15 | 6379 | 配置 replicaof 指向主节点 |
部署命令(关键步骤)
-
所有节点关闭防火墙与 SELinux
systemctl stop firewalld && systemctl disable firewalld setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
-
安装 Redis(所有节点)
yum install -y gcc gcc-c++ make tar zxvf redis-5.0.7.tar.gz -C /opt/ cd /opt/redis-5.0.7 && make && make PREFIX=/usr/local/redis install ln -s /usr/local/redis/bin/* /usr/local/bin/ # 建立软链接,方便命令调用
-
配置 Master 节点(192.168.100.47)
vim /etc/redis/6379.conf bind 0.0.0.0 # 70行:监听所有网卡,允许从节点连接 daemonize yes # 137行:后台运行 logfile /var/log/redis_6379.log # 172行:日志路径(方便排查问题) dir /var/lib/redis/6379 # 264行:数据存储目录 appendonly yes # 700行:开启 AOF 持久化(避免数据丢失)
启动 Master:
/etc/init.d/redis_6379 restart
-
配置 Slave 节点(192.168.100.48/49)
vim /etc/redis/6379.conf # 复制 Master 的基础配置(bind/daemonize/logfile/dir/appendonly) replicaof 192.168.100.47 6379 # 288行:指定主节点 IP 和端口 replica-read-only yes # 294行:从节点只读(默认开启,避免误写)
启动 Slave:
/etc/init.d/redis_6379 restart
-
验证主从状态(关键!)在 Master 节点执行,确认从节点数量为 2:
redis-cli info replication | grep "connected_slaves" # 正确输出:connected_slaves:2
2.3 常见问题:PID 文件残留(你遇到的 “进程已运行” 错误)
问题现象
启动 Redis 时提示:/var/run/redis_6379.pid exists, process is already running or crashed
,但实际进程已不存在。
原因分析(核心!)
- 异常关闭导致 PID 文件未清理:当 Redis 进程被
kill -9
强制杀死、服务器意外断电或 Redis 崩溃时,Redis 没有机会执行 “清理 PID 文件” 的收尾操作,导致/var/run/redis_6379.pid
残留。 - PID 文件权限问题:若 Redis 进程由 root 启动,后续用普通用户重启时,普通用户无权限删除 root 生成的 PID 文件,也会触发该提示。
解决步骤
bash
# 1. 确认进程是否真的存在(若输出为空,说明进程已死)
ps -ef | grep redis-server | grep -v grep# 2. 若进程不存在,删除残留的 PID 文件
rm -f /var/run/redis_6379.pid# 3. 重新启动 Redis
/etc/init.d/redis_6379 start# 4. (可选)预防措施:修改 Redis 配置,指定 PID 文件路径(避免权限冲突)
vim /etc/redis/6379.conf
pidfile /var/run/redis/redis_6379.pid # 150行:自定义 PID 路径(需先创建 /var/run/redis 目录)
mkdir -p /var/run/redis && chown redis:redis /var/run/redis
三、哨兵模式:主从集群的 “故障管家”
主从复制的缺陷是 “主节点宕机后需手动切换”,哨兵模式通过 “监控 + 自动选举” 解决此问题,实现真正的高可用。
3.1 核心原理(你必须理解的 3 个阶段)
- 监控阶段:每个哨兵节点每 1 秒向主节点、从节点及其他哨兵发送
PING
命令,检测节点存活状态。 - 主观下线(SDOWN):若一个哨兵在
down-after-milliseconds
(默认 30 秒)内未收到主节点的PONG
响应,会标记主节点为 “主观下线”(仅自己认为主节点死了)。 - 客观下线(ODOWN):当超过
quorum
(配置文件中指定的票数,如 2)个哨兵都标记主节点为 “主观下线”,则主节点被判定为 “客观下线”(集群公认主节点死了)。 - 故障转移:
- 哨兵集群通过 Raft 算法选举一个 “哨兵 leader”,由 leader 执行故障转移。
- 从节点选举规则:先选优先级高(
replica-priority
)的从节点,优先级相同则选复制偏移量最大(数据最完整)的从节点。 - 新主节点产生后,哨兵通知所有从节点指向新主,原主节点恢复后变为从节点。
3.2 完整部署步骤(基于已有主从集群)
环境准备
所有节点(Master/Slave1/Slave2)均部署哨兵,哨兵默认端口 26379。
部署命令(关键步骤)
-
所有节点配置哨兵文件
bash
vim /opt/redis-5.0.7/sentinel.conf protected-mode no # 17行:关闭保护模式(允许跨节点通信) port 26379 # 21行:哨兵默认端口 daemonize yes # 26行:后台运行 logfile "/var/log/sentinel.log" # 36行:哨兵日志路径(排查故障必备) dir "/var/lib/redis/6379" # 65行:数据存储目录 # 84行:监控主节点(mymaster是集群名,192.168.10.23是主节点IP,quorum=2表示需2个哨兵确认下线) sentinel monitor mymaster 192.168.100.47 6379 2 sentinel down-after-milliseconds mymaster 30000 # 113行:30秒未响应标记为下线 sentinel failover-timeout mymaster 180000 # 146行:故障转移超时时间(180秒)
-
启动哨兵(所有节点,先启主节点哨兵)
bash
redis-sentinel /opt/redis-5.0.7/sentinel.conf & # 后台启动
-
验证哨兵状态(任意节点)
bash
redis-cli -p 26379 info Sentinel # 正确输出应包含: # master0:name=mymaster,status=ok,address=192.168.100.47:6379,slaves=2,sentinels=3
-
故障模拟(验证自动切换)
bash
# 1. 在 Master 节点杀死 Redis 进程 ps -ef | grep redis-server | grep 6379 # 找到主节点进程号 kill -9 进程号# 2. 查看哨兵日志,确认故障转移 tail -f /var/log/sentinel.log # 关键日志:+switch-master mymaster 192.168.100.47 6379 192.168.100.48 6379(切换到 100.48 为新主)# 3. 验证新主节点状态 redis-cli -p 26379 info Sentinel # 输出应显示:address=192.168.100.48:6379(新主节点 IP)
3.3 常见问题:哨兵端口被占用(你遇到的 “Address already in use”)
问题现象
启动哨兵时提示:Could not create server TCP listening socket *:26379: bind: Address already in use
。
原因分析
- 之前的哨兵进程未正常关闭,残留进程占用 26379 端口。
- 误启动多个哨兵进程,导致端口冲突。
解决步骤
# 1. 查找占用 26379 端口的进程
netstat -tulpn | grep 26379 # 或 ps -ef | grep redis-sentinel# 2. 杀死残留进程
kill -9 进程号# 3. 重新启动哨兵
redis-sentinel /opt/redis-5.0.7/sentinel.conf &
四、集群模式:海量数据的解决方案
当数据量超过单机内存限制(如 100GB),主从和哨兵模式无法满足需求,此时需用集群模式通过 “哈希槽分片” 将数据分散到多个主节点。
4.1 核心原理(你实操中遇到的 “重定向” 本质)
-
哈希槽分片:集群共有 16384 个哈希槽(0-16383),每个主节点负责一部分槽位(如 3 主节点时,6001 负责 0-5460,6002 负责 5461-10922,6003 负责 10923-16383)。数据存储规则:
槽位 = CRC16(key) % 16384
,key 会自动路由到负责该槽位的主节点。 -
主从备份:每个主节点对应至少 1 个从节点(如 6001 主 → 6004 从,6002 主 → 6005 从),主节点宕机时,从节点自动升为主节点,保证槽位不丢失。
-
跨节点通信:节点间通过 “Gossip 协议” 交换集群信息(如节点状态、槽位分配),无需中心化管理。
4.2 完整部署步骤(单虚拟机模拟 6 节点,你实操的场景)
环境准备
在 1 台虚拟机上用端口区分 6 个节点(3 主 3 从):
节点角色 | 端口 | 对应从节点 | 负责槽位范围 |
---|---|---|---|
主节点 1 | 6001 | 6004 | 0-5460 |
主节点 2 | 6002 | 6005 | 5461-10922 |
主节点 3 | 6003 | 6006 | 10923-16383 |
从节点 1 | 6004 | - | 备份 6001 的槽位 |
从节点 2 | 6005 | - | 备份 6002 的槽位 |
从节点 3 | 6006 | - | 备份 6003 的槽位 |
部署命令(关键步骤,含你遇到的 6001 端口问题解决)
-
创建节点目录与复制文件
# 1. 创建 6 个节点目录 mkdir -p /etc/redis/redis-cluster/redis600{1..6}# 2. 复制 Redis 可执行文件和配置文件到每个目录 for i in {1..6}; docp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i/cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis600$i/ done
-
修改节点配置(以 6001 为例,其他节点改端口即可)
vim /etc/redis/redis-cluster/redis6001/redis.conf # bind 127.0.0.1 # 69行:注释掉,避免仅本地访问(你遇到的 6001 连接问题根源) bind 0.0.0.0 # 新增:监听所有网卡,允许跨端口通信 protected-mode no # 88行:关闭保护模式 port 6001 # 92行:节点端口(6002-6006 依次改端口) daemonize yes # 136行:后台运行 cluster-enabled yes # 832行:开启集群模式 cluster-config-file nodes-6001.conf # 840行:集群配置文件(6002-6006 改对应端口) cluster-node
常见错误
[root@master redis-5.0.7]# /etc/init.d/redis_6379 start
/var/run/redis_6379.pid exists, process is already running or crashed出现这个提示是因为 Redis 进程的 PID 文件(/var/run/redis_6379.pid)未被正确清理,导致系统误认为进程仍在运行。可以按以下步骤解决:
1. 检查是否有残留的 Redis 进程
ps -ef | grep redis-server | grep -v grep
如果有输出,说明进程确实在运行,无需重复启动(直接使用即可)。
如果无输出,说明进程已崩溃,但 PID 文件残留。
2. 清理残留的 PID 文件并重启
# 删除残留的PID文件
sudo rm -f /var/run/redis_6379.pid# 重新启动Redis服务
/etc/init.d/redis_6379 start