记一次生产环境Redis主从同步异常事故

故障生产环境zabbix突然告警,redis主从服务器的CPU使用率过高 。通过堡垒机连接生产服务器查看具体情况 。发现占用CPU较高的是redis进程 。
遂进一步查看redis实例的日志,发现进行几个小时内,从库出现了多次尝试重新连接主库的日志信息 。同样,主库redis日志中也出现了类似的日志信息:
182780:M 25 Apr 2020 14:00:57.423 * Replica 10.135.11.2:6379 asks for synchronization182780:M 25 Apr 2020 14:00:57.423 * Full resync requested by replica 10.135.11.2:6379182780:M 25 Apr 2020 14:00:57.423 * Can't attach the replica to the current BGSAVE. Waiting for next BGSAVE for SYNC155515:C 25 Apr 2020 14:05:10.743 * DB saved on disk155515:C 25 Apr 2020 14:05:11.463 * RDB: 2546 MB of memory used by copy-on-write182780:M 25 Apr 2020 14:05:12.701 * Background saving terminated with success182780:M 25 Apr 2020 14:05:12.701 * Starting BGSAVE for SYNC with target: disk182780:M 25 Apr 2020 14:05:13.562 * Background saving started by pid 155647182780:M 25 Apr 2020 14:05:40.585 # Client id=6140013 addr=10.135.11.2:42026 fd=631 name= age=283 idle=283 flags=S db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=14930 oll=13092 omem=268438368 events=r cmd=psync scheduled to be closed ASAP for overcoming of output buffer limits.182780:M 25 Apr 2020 14:05:40.646 # Connection with replica 10.135.11.2:6379 lost.根据上面的日志,不难发现其中的关键信息:
cmd=psync scheduled to be closed ASAP for overcoming of output buffer limits.问题根源经查资料,上面提示的关键信息意思是:
psync的命令超过了output-buffer-limits参数给定的限制值,master主动关闭了slave的连接 。然后slave又重新尝试连接master实例请求同步,同样的,无论请求多少次,都会由于这个参数的限制,同步失败,继而周而复始,陷入了恶性循环 。slave找master做全同步的过程是一个很消耗cpu消耗io消耗带宽的过程,所以会一直持续地告警 。
一句话总结问题:生产环境数据量过大,主备切换以后要同步的数据过大 。Slave实例请求同步的过程中,达到了参数 output-buffer-limits的最大值,被主库强制断开连接 。从库多次尝试重新同步主库的数据 。
解决方案调整redis实例 output-buffer-limits 参数值 。
redis 默认配置中,该参数的配置项为:
【记一次生产环境Redis主从同步异常事故】client-output-buffer-limit slave 256mb 64mb 60该参数作为redis的一项自我保护机制,默认硬性限制为256MB,或者达到软限制64MB后,并持续60秒钟,master实例会强制断开与slave的连接 。
解决方法:
# 登录Master实例执行如下命令,取消针对slave这种客户端类型的限制127.0.0.2:6379>config set client-output-buffer-limit 'slave 0 0 0'# 执行 config rewrite 将变更保存到redis配置文件127.0.0.2:6379>config rewrite

记得登录Slave实例执行同样的操作,以免Redis在下一次出现主从切换后,出现同样的问题 。
参数解析该参数配置格式:
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>具体参数含义如下:
class: 客户端种类,包括Normal,Slaves和Pub/Sub
  • Normal: 普通的客户端 。默认limit 是0,也就是不限制 。
  • Pub/Sub: 发布与订阅的客户端的 。默认hard limit 32M,soft limit 8M/60s 。
  • Slaves: 从库的复制客户端 。默认hard limit 256M,soft limit 64M/60s 。
hard limit: 缓冲区大小的硬性限制 。
soft limit: 缓冲去大小的软性限制 。
soft seconds: 缓冲区大小达到了(超过)soft limit值的持续时间 。
 
当client buffer的大小达到了soft limit并持续了soft seconds时间,master会立即断开和客户端的连接;
当client buffer的大小达到了hard limit,master会立即断开和客户端的连接 。




    推荐阅读