Redis内存溢出导致Sentinel主从切换失败,根源在于实例进入只读或拒绝写入状态,使探测命令失效。优化措施包括启用allkeys-lru淘汰策略、设置主库主动降级参数、用cgroup硬性限制内存,并调整tcp-keepalive与down-after-milliseconds。验证需手动触发failover,检查switch-master及last-p
先说结论:根本原因不是Sentinel本身挂了,而是它依赖的Redis实例在OOM时进入只读或拒绝写入状态,导致Sentinel无法执行INFO、CONFIG GET等探测命令,误判主节点下线。更隐蔽的是——当主库used_memory逼近maxmemory,且淘汰策略配的是noeviction时,写命令直接返回(error) OOM command not allowed when used memory > 'maxmemory'。Sentinel发心跳失败后,触发误切。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
先确认Sentinel进程自身是否健康,再排查它连接的Redis实例。具体操作很简单:
redis-cli -p 26379 ping —— 看Sentinel是否响应。redis-cli -p 26379 sentinel masters —— 查主节点状态字段中flags是否含s_down或o_down。redis-cli info memory | grep -E "used_memory|maxmemory|mem_fragmentation_ratio",若used_memory == maxmemory且mem_fragmentation_ratio > 1.5,Sentinel大概率已失联。Sentinel本身不管理内存,但可以用外部机制防止它因Redis OOM而误判。核心思路是让主库在内存压力下主动降级,而不是被动崩溃:
maxmemory-policy allkeys-lru(别用noeviction),避免写入直接失败。min-slaves-to-write 1和min-slaves-max-lag 10,让主库在从库延迟过大或掉线时主动拒绝写入,这比OOM后被动崩溃要可控得多。redis-cli --bigkeys定期扫描,对识别出的>1MB的hash或zset key加上EXPIRE,防止单key吃光内存。memory.max(Linux cgroup v2),比Redis自身maxmemory更硬性,避免jemalloc分配超限。改完配置必须验证Sentinel能否真正感知到主库恢复,而不是卡在“半下线”状态。这里有几个关键操作:
redis-cli -p 26379 sentinel failover mymaster,观察日志是否出现+switch-master。redis-cli config set maxmemory 4gb → redis-cli flushdb → 再config set maxmemory 8gb,看Sentinel是否重连并更新is-master-down-by-addr结果。redis-cli -p 26379 sentinel sentinels mymaster输出里每个sentinel的last-ping-reply和last-ok-ping-reply时间差,超过down-after-milliseconds值就说明通信仍异常。最易被忽略的是:Sentinel默认每10秒发一次INFO,但若主库OOM后响应缓慢,Sentinel可能在超时前就重试三次,累积大量TIME_WAIT连接,最终耗尽文件描述符。所以,调大tcp-keepalive和降低down-after-milliseconds要同步做,不能只改一个。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述