Redis执行save命令触发集群故障转移,改用bgsave可否解决该问题?
问题根因分析
- 触发故障的核心原因是使用了
save命令执行备份:Redis是单线程架构,save属于同步阻塞操作,执行期间会完全停止处理所有请求,包括集群节点间心跳探测、主从复制通信、Sentinel探活请求。当探活超时超过集群/Sentinel配置的阈值后,就会判定主节点故障,触发主备切换。 - 从提供的日志也能印证问题:执行save后4秒就出现了pub/sub客户端因为输出缓冲区超限被关闭的告警,后续连续出现节点FAIL判定,都是主进程阻塞期间请求堆积无法处理导致的。
改用
bgsave的效果 改用bgsave可以解决绝大多数场景下的该问题:
bgsave会fork一个子进程后台完成RDB文件写入,主进程全程几乎不阻塞,可以正常处理所有心跳、业务请求,不会触发探活超时判定。- 注意存在两个边界场景需要提前规避:
- 如果Redis单实例内存超过10G,fork子进程的操作会出现毫秒级到秒级的短暂阻塞,建议提前压测确认阻塞时长是否低于集群的探活超时阈值
- 要确保服务器剩余内存足够容纳fork过程的内存占用(Linux开启Copy-On-Write机制的话内存占用会低很多),避免触发OOM kill导致节点故障
额外优化建议
- 优先选择在从节点执行备份操作,完全不影响主节点的业务可用性,风险更低
- 如果集群已经开启了自动save持久化,可以直接备份自动生成的RDB文件,无需主动执行持久化命令,避免重复执行持久化占用服务器IO、内存资源
- 建议适当调大
client-output-buffer-limit参数中pub/sub、主从复制的缓冲区上限,避免大流量场景下出现客户端被强制断开的问题
内容的提问来源于stack exchange,提问作者Tom Meyer
相关产品推荐
相关产品推荐

