天天看點

Redis被bgsave和bgrewriteaof阻塞的解決方法

Redis 是一個性能非常高效的記憶體 Key-Value 存儲服務, 同時它還具有兩個非常重要的特性: 1. 持久化; 2. Value 資料結構. 這兩個特性讓它在不少場景輕松擊敗了 Memcached 和 Casandra 等.

Redis 的持久化在兩種方式: Snapshotting(快照) 和 Append-only file(aof). 在一個采用了 aof 模式的 Redis 伺服器上, 當執行 bgrewriteaof 對 aof 進行歸并優化時, 出現了 Redis 被阻塞的問題, 此時, Redis 無法提供任何讀取和寫入操作.

按字面了解, bgrewriteaof 是在背景進行操作, 不應該影響 Redis 的正常服務. 原理也确實是這樣的, Redis 首先 fork 一個子程序, 并在該子程序裡進行歸并和寫持久化儲存設備(如硬碟)的. 按照正常邏輯, 在一台多核的機器上, 即使子程序占滿 CPU 和硬碟, 也不應該導緻 Redis 服務阻塞啊!

其實, 問題就出在硬碟上.

Redis 服務設定了 appendfsync everysec, 主程序每秒鐘便會調用 fsync(), 要求核心将資料”确實”寫到存儲硬體裡. 但由于子程序同時也在寫硬碟, 進而導緻主程序 fsync()/write() 操作被阻塞, 最終導緻 Redis 主程序阻塞了.

解決方法便是設定 no-appendfsync-on-rewrite yes, 在子程序處理和寫硬碟時, 主程序不調用 fsync() 操作. 注意, 即使程序不調用 fsync(), 系統核心也會根據自己的算法在适當的時機将資料寫到硬碟(Linux 預設最長不超過 30 秒).

繼續閱讀