本文將介紹Redis持久化的兩種方式:快照持久化和AOF持久化,並對兩種方法進行分析和對比,方便在實際中做出選擇。
持久化
什么是持久化
Redis所有數據保存在內存中,對數據的更新將異步地保存到磁盤上,使得數據在Redis重啟之后仍然存在。這么做這有什么實際意義呢?將數據存儲到硬盤是為了以后可以重用數據,將數據進行備份,可以在系統故障的時候從備份進行恢復。還有一點,存儲在Redis里面的數據可能是經過復雜運算而得出的結果,把這些數據進行存儲,方便后續的使用,以達到“空間換時間”的效果。
持久化的實現方式
Redis提供了兩種不同的持久化方法將數據保存到硬盤里面。
快照持久化:將Redis某一時刻存在的所有數據都寫入硬盤。
AOF持久化:AOF的全稱叫append-only file,中文意思是只追加文件。當使用AOF持久化方式的時候,Redis執行寫命令的時候,將被執行的寫命令復制到硬盤里面,說的通俗一點就是寫日志。
快照持久化
什么是快照持久化
Redis通過創建快照來獲得存儲在內存里面的數據在某個時間節點上的副本。
觸發機制-主要三種方式
-
save(同步)
-
bgsave(異步)
-
自動


save命令和bgsave命令對比:
命令
|
save
|
bgsave
|
IO類型
|
同步
|
異步
|
是否阻塞
|
是
|
是
|
復雜度
|
O(n)
|
O(n)
|
優點
|
不會消耗額外內存
|
不阻塞客戶端命令
|
缺點
|
阻塞客戶端命令
|
需要fork,消耗內存
|

快照持久化選項:
多久執行一次自動快照操作,60s之內有1000次操作寫入時執行 save 60 1000 創建快照失敗后是否仍然繼續執行寫命令 stop-writes-on-bgsave-error no 是否對快照文件進行壓縮 rdbcompression yes 命名硬盤上的快照文件 dbfilename dump.rdb
最佳配置:
dbfilename dump-${port}.rdb dir /bigdiskpath stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes
AOF持久化
快照持久化現存問題
耗時、耗性能:通過bgsave命令進行持久化的的時候,需要fork一個子進程,如果數據量很大的話,需要的內存也會相應的變大,內存的占用會導致Redis性能降低。
不可控、丟失數據:舉個例子,上一次創建快照是11:00開始創建並創建成功。如果Redis在12:00開始創建新的快照,如果系統在未完成創建快照之前崩潰,11:00-12:00寫入的數據將會丟失;如果系統在快照創建完成之后崩潰,那么12:00之后,創建快照的過程中的數據將會丟失。
什么是AOF
AOF持久化將被執行的寫命令寫到AOF文件的末尾,以達到記錄數據的目的。Redis只要從頭到尾重新執行一次AOF所有的命令就可以恢復數據。


AOF三種策略



三種策略對比:生產環境中需要根據實際的需求進行選擇。
命令 | always | everysec | no |
優點 | 不丟失數據 | 每秒一次fsync | 不用管 |
缺點 | IO開銷較大,一般的SATA盤只有幾百TPS | 丟1s數據 | 不可控 |
AOF重寫
隨着Redis的運行,被執行的寫命令不斷同步到AOF文件中,AOF文件的體積越來越大,極端情況將會占滿所有的硬盤空間。如果AOF文件體積過大,還原的過程也會相當耗時。為了解決AOF文件不斷膨脹的問題,需要移除AOF文件中的冗余命令來重寫AOF。
原生AOF | AOF重寫 |
set hello world
set hello java
set hello redis
incr counter
inct counter
rpush mylist a
rpush mylist b
rpush mylist c
過期數據
|
set hello redis
set counter 2
rpush mylist a b c
|
-
bgrewriteaof命令
bgrewriteaof命令和bgsave命令的工作原理相似:Redis創建一個子進程,然后由子進程負責對AOF文件進行重寫。

-
AOF重寫配置
配置參數說明:
名稱 | 含義 |
auto-aof-rewrite-min-size | AOF文件重寫需要的尺寸 |
auto-aof-rewrite-percentage | AOF文件增長率 |
具體配置:
appendonly yes appendfilename "appendonly-${port}.aof" appendfsync everysc dir /bigdiskpath no-appendfsync-on-rwrite yes auto-aof-rewrit-percentage 100 auto-aof-rewrite-min-size 64mb
快照持久化和AOF持久化的對比和選擇
對比
命令 | 快照持久化 | AOF持久化 |
啟動優先級 | 低 | 高 |
體積 | 小 | 大 |
恢復速度 | 快 | 慢 |
數據安全性 | 丟數據 | 根據策略決定 |
輕重 | 重 | 輕 |
選擇
在實際生產環境中,根據數據量、應用對數據的安全要求、預算限制等不同情況,會有各種各樣的持久化策略;如完全不使用任何持久化、使用快照持久化或AOF持久化的一種,或同時開啟快照持久化和AOF持久化等。此外,持久化的選擇必須與Redis的主從策略一起考慮,因為主從復制與持久化同樣具有數據備份的功能,而且主機master和從機slave可以獨立的選擇持久化方案。
(1)如果Redis中的數據完全丟棄也沒有關系(如Redis完全用作DB層數據的cache),那么無論是單機,還是主從架構,都可以不進行任何持久化。
(2)在單機環境下(對於個人開發者,這種情況可能比較常見),如果可以接受十幾分鍾或更多的數據丟失,選擇快照持久化對Redis的性能更加有利;如果只能接受秒級別的數據丟失,應該選擇AOF。
(3)但在多數情況下,我們都會配置主從環境,slave的存在既可以實現數據的熱備,也可以進行讀寫分離分擔Redis讀請求,以及在master宕掉后繼續提供服務。在這種情況下,一種可行的做法是:master:完全關閉持久化,這樣可以讓master的性能達到最好slave:關閉快照持久化,開啟AOF(如果對數據安全要求不高,開啟快照持久化關閉AOF也可以),並定時對持久化文件進行備份(如備份到其他文件夾,並標記好備份的時間);然后關閉AOF的自動重寫,然后添加定時任務,在每天Redis閑時(如凌晨12點)調用bgrewriteaof。