Redis學習筆記(五) - RDB持久化

Redis支持 RDBAOF兩種持久化機制,持久化功能有效地避免因進程退出形成的數據丟失問題,當下次重啓時利用以前持久化的文件便可實現數據恢復.掌握持久化機制對於學習 Redis很是重要.

RDB持久化是把當前進程數據生成快照保存到硬盤的過程,出發RDB持久化過程分發手動觸發和自動觸發redis

一.觸發機制

手動觸發分別對應savebgsave命令:算法

  • save命令:阻塞當前Redis服務器,直到RDB過程完成爲止,對於內存比較大的實例會形成長時間阻塞,線上環境不建議使用.運行save命令對應的Redis日誌是:
* DB saved on disk
  • bgsave命令:Redis進程執行fork操做建立子進程,RDB持久化過程由子進程負責,完成後自動結束.阻塞只發生在fork階段,通常時間很短.運行bgsave命令對應的Redis日誌以下:
* Background saving started by pid 3177
    * DB saved on disk
    * RDB: 0MB of memory used by copy-on-write
    * Background saving terminated with success

顯然bgsave命令是針對save阻塞問題作的優化版本.所以Redis內部全部的涉及RDB的操做都採用bgsave的方式,而save命令已經廢棄.服務器

除了執行命令手動觸發以外,Redis內部還存在自動觸發RDB的持久化機制,例如如下場景:併發

  1. 使用save相關配置,如save a b.表示a秒內數據集存在b次修改後,自動觸發bgsave.
  2. 若是從節點執行全量複製操做,主節點自動執行bgsave生成RDB文件併發送給從節點.
  3. 執行debug reload命令從新加載Redis時,也會自動觸發save操做.
  4. 默認狀況下執行shutdown命令時,若是沒有開啓AOF持久化功能則自動執行bgsave.

二.流程說明

bgsave是主流的出發RDB持久化方式,下圖說明了它的運做流程.工具

bgsave 命令的運做流程

  1. 執行bgsave命令,Redis父進程判斷當前是否存在正在執行的RDB/AOF子進程,存在直接返回不存在進行下一步.
  2. 主線程執行fork操做建立子進程,fork操做過程當中父進程會阻塞,經過info stats命令查看latest_fork_usec選項,能夠獲取最近一個fork操做的耗時,單位爲毫秒.
  3. 父進程fork完成後,bgsave命令返回Background saving started信息並阻塞父進程,能夠繼續相應其餘命令.
  4. 子進程建立RDB文件,根據父進程內存生成臨時快照文件,完成後對原有文件進行原子替換.執行lastsave命令能夠獲取最後一次生成RDB的時間,對應info統計的rdb_last_save_time選項.
  5. 進程發送信號給父進程表示完成,父進程更新統計信息,具體詳見info Persistence下的rdb_*相關選項.

三.RDB文件的處理

保存:RDB文件保存在dir配置指定的目錄下,文件名經過dbfilename配置指定.能夠經過config dir [newDir]config dbfilename [newFileName]容許期動態執行,當下次運行時RDB文件會保存到對應的新目錄.
壓縮:Redis默認採用LZF算法對生成的RDB文件作壓縮處理,壓縮後的文件遠遠小於內存大小,默認開啓,能夠經過參數config set rdbcompression {yes|no}動態修改.
校驗:若是Redis加載損壞的RDB文件時拒絕啓動,並打印以下日誌:學習

# Short read or OOM loading DB. Unrecoverable error, aborting now.

這是可使用Redis提供的redis-check-dump工具檢測RDB文件並獲取對應的錯誤報告.優化

四.RDB的優勢

RDB的優勢:spa

  • RDB是一個緊湊壓縮的二進制文件,表明Redis在某個時間點上的數據快照.很是適用於備份,全量複製等場景.好比每6個小時執行bgsave備份,並把RDB文件拷貝到遠程機器或文件系統中(如:hdfs)用於災難恢復.
  • Redis加載RDB恢復數據速度遠快於AOF的方式.

RDB的缺點:線程

  • RDB方式數據沒辦法作到實時持久化/秒級持久化.由於bgsave每次運行都要執行bgsave每次運行都要執行fork操做建立子進程,屬於重量級的操做,頻繁操做的成本過高.
  • RDB文件使用特定的二進制格式保存,Redis版本演進過程當中有多個格式的RDB版本,存在老版本Redis服務沒法兼容新版RDB格式的問題.
相關文章
相關標籤/搜索