Redis有兩種方式進行持久化:RDB和AOF
RDB持久化方式
Redis默認是開啟RDB持久化方式的,RDB持久化可以通過在客戶端執行save或bgsave命令主動進行數據持久化磁盤,或者在配置文件中配置觸發bgsave的規則,在滿足配置的規則時自動觸發bgsave命令進行數據持久化
save是阻塞方式的在持久化過程中不處理客戶端的操作請求,save命令只有在需求明確需要數據進行持久化比如關機維護等
在客戶端中連續set k1的值為a、b、c,然後執行save命令
可看到控制檯日誌,進行數據的持久化
此時在配置數據文件的目錄下會生成一個.rdb的文件dump.rdb(文件名在配置文件中可配置)
文件內容是以REDIS開頭的如下圖所示
bgsave是通過調用系統系統函數fork()創建出一個子進程,在子進程中進行數據的持久化,過程中不影響繼續處理客戶端請求,且在持久化過程中主進程對數據的修改不會影響子進程中數據的時點性。
手動執行bgsave命令
控制檯日誌輸出
在調用fork()創建的子進程會的虛擬內存地址中複製一份虛擬內存地址到物理內存地址的映射,即主進程和子進程虛擬地址的指針指向同一個物理內存地址,主進程發生數據的寫操作時使用內核的copy on write機制指向物理內存的一個新的地址,此時子進程執行的還是原來的內存地址。
因為Linux中進程間數據是隔離的,所以主進程對數據的改變對子進程是不可見的,子進程對數據的改變對主進程也是不可見的。
配置文件規則:
60秒發生1000次寫請求、300秒發生10次寫請求、900秒發生一次寫請求都會觸發bgsave對內存中的數據進行rdb持久化
save 900 1
save 300 10
save 60 1000
持久化生成的rdb文件名
dbfilename dump.rdb
持久化rdb文件保存的路徑
dir /var/lib/redis/6379
RDB方式持久化優缺點:
優點:
1、rdb文件相對較小
2、類似於Java中的序列化方式存儲,恢復數據速度相對較快
缺點:
1、不支持拉鍊,只有一個dump.rdb文件,每次都是覆蓋
2、丟失數據相對多些,時點與時點之間窗口的數據容易丟失,如數據未持久化時宕機會丟失上次持久化時點到宕機這個時間窗口內的數據
AOF持久化方式
Redis的每次寫操作都會追加到aof文件中,AOF持久化方式默認是關閉的,若想要開啟AOF持久化方式則需要修改配置參數appendonly 為 yes,若同時開啟了RDB和AOF持久化開機時使用aof文件進行數據的恢復。
開啟aof持久化方式
appendonly yes
aof文件名
appendfilename "appendonly.aof"
寫操作寫入磁盤的配置:
appendfsync always
appendfsync everysec
appendfsync no
always:每次寫操作都會執行flush寫入磁盤,會丟失一次寫操作的數據
everysec:每秒執行一次flush寫入磁盤,會丟失不超過一個buffer緩衝區大小的數據,因為一秒內數據若大小超過buffer緩衝區大小,內核會自動寫入磁盤
no:不主動執行flush寫入磁盤,數據都會寫入到內核的buffer緩衝區,緩衝區滿了之後由內核執行寫入磁盤,會丟失不超過一個buffer緩衝區大小的數據
aof文件重寫:
Redis4.0以前的版本執行BGREWRITEAOF命令會刪除抵消的命令合併重複的命令,最終生成的也是一個純指令的日誌文件
Redis4.0以後的版本執行BGREWRITEAOF命令會將老的數據以RDB快照的方式寫入到aof文件中,後續發生的寫操作會以指令的方式追加到aof文件中,aof文件是一個混合體利用的RDB的快和AOF的全量
連續set k1的值為1、2、3
查看aof文件,因為此前沒有執行過重寫aof文件的操作,所有的命令都是追加的方式寫入到aof文件
*2:下面的操作包含兩個指令
$6:下一個指令是6個字符
執行BGREWRITEAOF命令執行重寫aof文件
再次查看aof文件,此時的aof文件是把以前的全部數據生成rdb快照寫入到aof文件中
再次執行寫操作
再次查看aof文件,BGREWRITEAOF之後執行的寫操作是以命令追加的方式寫的aof文件,此時是rdb和aof共存的一個混合體
配置自動執行BGREWRITEAOF命令
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
AOF方式持久化優缺點:
優點:
1、丟失數據相對較少
缺點:
1、aof文件體量無限變大,數據恢復較慢