最近生產環境中某個set的redis集群經常出現短暫的記憶體降低現象,經過檢視日誌是因為在rdb持久化所造成的記憶體突降(日誌中:rdb: 4929 mb of memory used by copy-on-write ),其根本原理是rdb持久化的過程中,redis借助作業系統提供的寫時複製技術(copy-on-write,cow),在執行bgs**e(snapshot)快照的同時,能夠處理正常的寫請求。
寫時複製技術:
如果主線程要修改一塊資料,那麼這塊資料就會被複製乙份,生成該資料的副本。然後bgs**e 子程序會把這個副本寫入正在持久化的rdb檔案,而在這個過程中,主線程仍然可以直接修改原來的資料。另外,子程序是會複製乙份和主程序一模一樣的虛擬頁表來對映記憶體,保證持久化檔案的完整性。
正因為資料會被額外的複製乙份,所以會占用額外的記憶體,當在進行rdb持久化操作的過程中,與此同時如果持續往redis中寫入的資料量越多,就會導致占用的額外記憶體消耗越大。
那麼在此期間寫入的資料去哪了呢?
寫入的資料還是存在了記憶體當中,並沒有寫入當前的持久化檔案中,等到下次進行rdb持久化時才會把 」 寫入的資料 」 落盤到rdb檔案中。
bgs**e:fork出的子程序開始根據父程序記憶體資料生成臨時的快照檔案,然後替換原檔案。
根據 rdb_bgs**e_in_progress 這一項為 0,可以判斷在執行 info persistence 命令時,bgs**e 已經執行完成了。
除了通過命令的方式觸發 rdb 持久化之外,redis 內部還有自動觸發 rdb 的機制。比如以下場景:
如果頻繁執行全量快照,會帶來兩方面的開銷:
3.1 rdb 所在分割槽磁碟滿了怎麼辦?
當遇到 rdb 所在分割槽磁碟滿了,可以臨時修改 rdb 路徑,操作如下:
3.2 開啟 rdb 壓縮
redis 支援對 rdb 進行壓縮,引數為 rdbcompression,設定為 yes 表示開啟(預設開啟的)。壓縮不但可以節省磁碟空間,在建立主從時,也能更快的將全量備份傳給從例項,因此建議開啟壓縮功能。
3.3 rdb 檔案損壞檢測
當發現 reids rdb 檔案損壞時,可以使用 redis-check-rdb 進行檢測,用法如下:
rdb looks ok! 說明rdb檔案沒有錯誤。
3.4 單機多例項的 rdb 備份
有些情況,我們會在單台伺服器上部署多個 redis 例項,但是使用配置檔案中增加 s**e 的方式又怕幾個例項 rdb 時間衝突,從而影響落盤速度。這種情況,可以使用指令碼結合定時任務觸發 bgs**e 進行 rdb 備份。這樣,同機器不同例項的 rdb 備份時間可以自定義錯開,防止 io 跑滿帶來的問題。(注意一定要設定好持久化的目錄,防止多個例項共用同一目錄)
那麼 redis 究竟怎麼備份更好呢?
rdb 儘管恢復會快很多,但是可靠性比 aof 低,但是如果只使用 aof,又會存在恢復慢的問題,因此,redis 4.0 提出了混合使用 aof 日誌和記憶體快照的方法。
因此對於 redis 的備份,建議如下:
當然,如果有從例項,也優先考慮在從例項上進行備份。
redis持久化之AOF持久化
aof與rdb持久化通過儲存資料庫中的鍵值對來記錄資料庫狀態不同,aof持久化是通過儲存redis伺服器所執行的寫命令來記錄資料庫狀態的。被寫入aof檔案的所有命令都是以redis的命令請求協議格式儲存的。當aof持久化功能處於開啟狀態,伺服器在執行完乙個寫命令之後,會以協議格式將被執行的寫命令追加...
Redis之持久化
aof中記錄的內容如下 其中,3 表示當前命令有三個部分,每部分都是由 數字 開頭,後面緊跟著具體的命令 鍵或值。這裡,數字 表示這部分中的命令 鍵或值一共有多少位元組。例如,3 set 表示這部分有 3 個位元組,也就是 set 命令。重寫機制具有 多變一 功能。所謂的 多變一 也就是說,舊日誌檔...
Hibernate通過註解寫持久化類
hibernate有兩種方法來寫對映檔案,當執行hibernate程式時,會先訪問hibernate.cfg.xml配置檔案讀取配置檔案中的資訊連線資料庫。然後訪問對映檔案的路徑無論是通過註解的形式還是hbm.xml的形式。如果資料庫中沒有持久化類所對應的表,那麼會自動生成表。通過註解寫持久化類 e...