一、为什么Redis需要哨兵模式?
1.1 主从复制的“痛点”
很多开发者刚接触Redis高可用,会先搭主从结构:一台当主节点负责写,几台当从节点同步数据负责读。但这个结构有个致命问题——主节点是单点,一旦主节点躺平,整个服务就崩了,业务的写请求全失败,还得运维手动操作:选个从节点提为主,修改其他从节点的主地址,重启服务,这一套下来快则几分钟,慢则十几分钟,对于电商大促、社交热帖这类业务来说,几分钟的停顿足够让用户流失一大片,所以必须有个能自动管这事的角色。
1.2 哨兵的核心作用
Redis的哨兵模式,就是专门解决主从结构的单点问题的。简单说,哨兵就是一群“盯着主从的监工”,至少要3个,互相通信,实时监控主节点、从节点和自己的状态:主节点挂了,哨兵们先自己判断是不是真的挂了,达成共识后,自动选一个从节点升成新主,再让其他从节点改连新主,最后通知业务方新的主地址,整个过程全自动化,不用人工干预,能把故障切换时间压缩到秒级,几乎不会影响业务。
二、哨兵模式的工作流程
2.1 哨兵的组成规则
哨兵集群的数量必须是奇数,最少3个,最多可以随便加,但3个已经足够。选奇数是因为后面要投票选主节点,少数服从多数,避免出现平局的情况。每个哨兵都会和所有主节点、从节点建长连接,不仅监控它们的状态,还会互相交换信息,确保对节点的状态判断准确。
2.2 故障转移的具体步骤
假设主节点真的挂了,整个故障转移是按步骤来的: 第一步,主观下线:每个哨兵自己先看主节点有没有响应,比如超过设置的时间(默认3秒)没收到主节点的回复,就会标记主节点为“疑似下线”,这是单个哨兵的判断,可能是网络延迟导致的误判。 第二步,客观下线:如果超过半数的哨兵都标记这个主节点为疑似下线,就会把它升级成“真的下线”,这就避免了单哨兵误判的问题,比如某个哨兵自己网络断了,不会影响整个集群的判断。 第三步,选新主:哨兵会从所有在线的从节点里选一个当新主,选的规则很简单:先选从节点优先级最高的(配置里的slave-priority参数,值越小优先级越高),如果优先级一样,就看runid(每个节点唯一的ID),runid小的优先,要是这俩都一样,就看复制的偏移量,偏移量越大说明同步的数据越多,越新。 第四步,调整主从关系:选好新主后,哨兵会让其他从节点断开旧主,连到新主上,让整个集群重新恢复数据同步。 第五步,通知客户端:哨兵会把新主的地址发给业务方,业务方之后就可以连新主写数据了。
三、哨兵模式的实操示例(技术栈:Redis 6.x)
为了让大家能实际跑起来感受哨兵模式的效果,这里给一个完整的实操步骤,所有操作都是命令行,没有复杂的配置,注释也会写清楚: 首先,我们需要准备3个哨兵实例、1个主节点、2个从节点,全部在本地跑,用bash命令操作:
# 1. 先创建3个哨兵的配置文件,每个哨兵端口不同,方便区分
# 哨兵1配置,端口26379,监控主节点(名称叫mymaster,地址127.0.0.1,端口6379,需要2个哨兵同意故障)
cat > sentinel1.conf << EOF
port 26379 # 哨兵监听的端口
daemonize yes # 后台运行
sentinel monitor mymaster 127.0.0.1 6379 2 # 监控的主节点信息,最后一个2是投票数
sentinel down-after-milliseconds mymaster 3000 # 3秒没响应就标记为疑似下线
sentinel failover-timeout mymaster 180000 # 故障转移的超时时间,3分钟
EOF
# 哨兵2配置,端口26380,和哨兵1一样监控同一个主节点
cat > sentinel2.conf << EOF
port 26380
daemonize yes
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 180000
EOF
# 哨兵3配置,端口26381,同样监控mymaster
cat > sentinel3.conf << EOF
port 26381
daemonize yes
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel failover-timeout mymaster 180000
EOF
# 2. 启动主节点和从节点,主节点端口6379,从节点分别是6380和6381
# 启动主节点,后台运行
redis-server --port 6379 --daemonize yes
# 启动从节点1,设置主节点为6379,后台运行
redis-server --port 6380 --slaveof 127.0.0.1 6379 --daemonize yes
# 启动从节点2,设置主节点为6379,后台运行
redis-server --port 6381 --slaveof 127.0.0.1 6379 --daemonize yes
# 3. 启动3个哨兵实例,每个实例用对应的配置文件
redis-server sentinel1.conf --sentinel
redis-server sentinel2.conf --sentinel
redis-server sentinel3.conf --sentinel
启动完后,我们可以验证一下集群状态:
# 查看哨兵监控的主节点信息,确认是否正常
redis-cli -p 26379 sentinel masters
# 查看从节点信息,确认两个从节点都连到主节点
redis-cli -p 26379 sentinel slaves mymaster
接下来模拟故障,停掉主节点,看哨兵的自动切换效果:
# 模拟主节点崩溃,关闭6379端口的Redis
redis-cli -p 6379 shutdown
过个10秒左右,再用命令查看哨兵的主节点,会发现主节点已经变成原来的从节点之一了,说明故障转移成功,不用手动操作,这就是哨兵模式的核心能力。
四、哨兵模式的应用场景
哨兵模式适合所有对Redis可用性有要求的业务场景,尤其是不能容忍长时间停机的场景:
- 电商平台:商品详情页的热点数据、用户的购物车缓存,一旦Redis崩了,用户无法查看商品,无法操作购物车,直接影响营收,哨兵能快速切换,减少损失。
- 社交平台:用户的会话缓存、帖子的热门数据,哨兵能保证这些数据的高可用,不会因为Redis故障导致用户掉线。
- 企业内部系统:比如OA系统的用户登录缓存,一旦躺平,员工无法登录系统,影响办公效率。
总的来说,只要你的业务用Redis做缓存,且不能接受长时间停机,哨兵模式都是合适的方案,它实现成本低,不需要额外的复杂组件,只要搭几个哨兵实例就行。
五、哨兵模式的技术优缺点
5.1 优点
- 自动故障转移:不用人工干预,故障切换时间短,能快速恢复服务。
- 兼容性好:和Redis主从复制完全兼容,不需要改动现有的主从结构,只要加哨兵就行。
- 哨兵自身高可用:哨兵是集群,只要至少2个哨兵正常,就能正常监控和故障转移,不会成为单点。
5.2 缺点
- 数据丢失风险:如果主节点挂了,没来得及同步到从节点的写数据会丢失,所以对数据一致性要求极高的场景(比如金融场景),哨兵模式可能不够,需要用更强的方案。
- 客户端适配问题:业务端需要适配哨兵的配置,不能直接连固定的主节点地址,需要让客户端连接哨兵,从哨兵那里获取最新的主节点地址,否则故障后业务会连不上。
- 故障转移时间:虽然比手动快,但还是有几秒钟的时间,对于完全不允许任何中断的场景,还是不够,需要用集群模式之类的方案。
六、注意事项
用哨兵模式的时候,有几个细节要注意,不然容易踩坑:
- 哨兵数量必须是奇数:最少3个,投票数要配置合理,比如3个哨兵的话,投票数设为2,这样只要2个哨兵达成共识就触发故障,既不会误判,也不会太迟钝。
- 网络配置要合理:哨兵和主从节点之间的网络要稳定,避免网络延迟导致的误判,比如设置的down-after-milliseconds不要太小,比如不要设成1秒,容易因为临时延迟误判主节点挂了。
- 主从复制的配置:要开启psync2功能,这能让从节点断线后重连时只同步缺失的数据,不需要全量同步,减少切换时间,也减少网络带宽占用。
- 持久化配置:如果需要防止数据丢失,主从节点要开启RDB或AOF持久化,避免主节点挂了后,从节点还没把数据同步到磁盘,导致数据丢失。
七、文章总结
哨兵模式是Redis实现高可用的核心方案之一,它通过一群哨兵实例的协同,解决了主从结构的单点问题,能自动完成故障切换,适合大部分中小规模、对可用性有要求的业务场景。本文从哨兵的作用、工作流程、实操示例、应用场景、优缺点到注意事项,都做了详细的讲解,希望不同基础的开发者都能快速理解并落地使用。只要注意配置细节,就能用哨兵模式搭建稳定的Redis高可用服务,避免因为单点故障导致的业务中断。
评论
围绕“Redis的哨兵高可用模式深入剖析”参与讨论