故障
生產環境zabbix突然告警,redis主從服務器的CPU使用率過高。通過堡壘機連接生產服務器查看具體情況。發現占用CPU較高的是redis進程。
遂進一步查看redis實例的日志,發現進行幾個小時內,從庫出現了多次嘗試重新連接主庫的日志信息。同樣,主庫redis日志中也出現了類似的日志信息:
182780:M 25 Apr 2020 14:00:57.423 * Replica 10.135.11.2:6379 asks for synchronization
182780:M 25 Apr 2020 14:00:57.423 * Full resync requested by replica 10.135.11.2:6379
182780:M 25 Apr 2020 14:00:57.423 * Can't attach the replica to the current BGSAVE. Waiting for next BGSAVE for SYNC
155515:C 25 Apr 2020 14:05:10.743 * DB saved on disk
155515:C 25 Apr 2020 14:05:11.463 * RDB: 2546 MB of memory used by copy-on-write
182780:M 25 Apr 2020 14:05:12.701 * Background saving terminated with success
182780:M 25 Apr 2020 14:05:12.701 * Starting BGSAVE for SYNC with target: disk
182780:M 25 Apr 2020 14:05:13.562 * Background saving started by pid 155647
182780: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 默認配置中,該參數的配置項為:
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會立即斷開和客戶端的連接。