進階的Redis之數據持久化RDB與AOF

你們都知道,Redis之因此性能好,讀寫快,是由於Redis是一個內存數據庫,它的操做都幾乎基於內存。可是內存型數據庫有一個很大的弊端,就是當數據庫進程崩潰或系統重啓的時候,若是內存數據不保存的話,裏面的數據就會丟失不見了。這樣的數據庫並非一個可靠的數據庫。redis

因此數據的持久化是內存型數據庫的重中之重。它不只提供數據保存硬盤的功能,還能夠藉此用硬盤容量擴展數據存儲空間,使得Redis的能夠存儲超過機器自己內存大小的數據。數據庫

Redis對於數據持久化提供了兩種持久化的方案,RDB與AOF。它們的原理和使用場景都大不相同,下面咱們來詳細地瞭解下。緩存

RDB——數據快照(Snapshot)

RDB,提供一個某個時間點的數據的Snapshot,保存在RDB文件中。它能夠經過SAVE/BGSAVE命令手動執行,把數據Snapshot寫到RDB文件,也能夠經過配置,定時執行。安全

Redis也能夠經過加載RDB文件,把數據從磁盤加載讀取到Redis中。微信

RDB文件建立

連上Redis,設值一些值,而後執行SAVE命令。 app

而後能夠查看下redis.conf的持久化工做目錄。進入目錄能夠看到保存了一個dump.rdb文件。該文件是一個二進制文件,沒法直接正常打開。 函數

至於SAVE/BGSAVE的區別,就是前置是阻塞執行,此時服務不會接受請求,後者是Fork一個子進程出來,由該進程去執行保存RDB文件的操做,不影響用戶請求。工具

P.S. Redis是單進程的,因此BGSAVE只能Fork一個子進程,而不是建立一個線程處理。性能

以上是手動執行的過程。但在生產咱們不多會手動登上服務去執行操做,因此更多的時候是依賴Redis的配置,定時保存RDB文件。操作系統

打開redis.conf配置文件,找到SNAPSHOTTING的配置,Save Point的設置。

圖中的配置意思是,當至少有一個key變動時,900秒後會執行一次SAVE。其餘配置同理,有10次變動,300秒後保存一次.....

在Redis中,這個自動保存RDB的功能是默認開啓的。

RDB文件加載

先kill掉Redis進程,再從新啓動Redis Server,會發現日誌會有這樣的一行,

而且Redis中,依然有以前設置的三個值。說明Redis在啓動的時候,會加載數據初始化。

不過,這裏加載的初始化數據不必定是RDB的。若是Redis開啓了AOF,會優先從AOF初始化數據,不然纔會加載RDB的數據。

RDB優缺點

優勢:

  1. RDB是某一時間點的快照,是一個緊湊的單文件,更多用於數據備份。能夠按每小時或每日來備份,方便從不一樣的版本恢復數據。
  2. 單文件容易傳輸到遠程服務作故障恢復。
  3. RDB能夠Fork子進程進行持久化,使Redis能夠更好地處理用戶請求
  4. 在大量數據的狀況下,RDB相比較於AOF會更快的加載。

缺點:

  1. 若是Redis不及時保存RDB文件,會形成數據的丟失。例如系統忽然斷電,但將來得及保存數據。即便你設置更多的Save point,也沒法保證100%的數據不丟失。
  2. RDB常常須要fork子進程去執行,但若是再大量數據的狀況下,這個fork操做會很是耗CPU資源的。對比AOF雖然也是fork,可是它的數據保存處理是能夠控制的,不須要全量保存。

AOF——日誌追加(Append-Only)

Redis的另一種持久化方案就是AOF,Append Only File。AOF至關於一個操做的日誌記錄,每次對於數據的變動都會記錄追加到AOF日誌。當服務啓動的時候就會讀這些操做日誌,從新執行一次操做,從而恢復原始數據。

AOF啓用

AOF默認是關閉的。打開redis.conf配置文件,找到appendonly no改爲appendonly yes

AOF和RDB是能夠共存的,只要保存的文件名不衝突。

AOF fsync同步規則

配置文件往下拉,看到fsync的配置。

fsync()是一個系統調用函數,告訴操做系統把數據寫到硬盤上,而不是緩存更多數據才寫到硬盤。這樣的調用能夠及時保存數據到硬盤上。

Redis提供了三種fsync的調用方式

  • appendfsync always,每次操做記錄都同步到硬盤上,最低效,最安全。
  • appendfsync everysec,每秒執行一次把操做記錄同步到硬盤上。默認選項。
  • appendfsync no,不執行fysnc調用,讓操做系統自動操做把緩存數據寫到硬盤上,不可靠,但最快。

AOF文件格式解析

開啓AOF後,會再工做目錄看到appendonly.aof文件。

在客戶端上執行一些命令後,打開AOF文件,能夠觀察到有對應的操做的記錄日誌。
文件解析說明:

  • *,表示命令的參數個數,例如set a 1是三個參數,因此是*3
  • $,表示參數的字節數,例如set這個參數是三字節,因此是$3,key值a是一個字節,因此是$1
  • 無符號,表示是參數的數據,例如set,a,1就是具體的數據

日誌重寫

AOF雖然比RDB更可靠,但缺點也是比較明顯的,就是每次寫操做都要把操做日誌寫到文件上,這樣會致使文件很是冗餘。

倘若你要自增一個計數器100次,若是不重寫,AOF文件就就會有這100次的自增記錄,如INCR a。若是執行了日誌重寫,那麼文件只會保留set a 100而不是100條INCR a。這樣擁有相同的結果,但能夠大大減小AOF的文件大小,而且可讓AOF載入的時候提高載入的效率。

看回redis.conf配置,有兩項控制rewrite的選項。

  • auto-aof-rewrite-percentage 100,當文件增加100%(一倍)時候,自動重寫。
  • auto-aof-rewrite-min-size 64mb,日誌重寫最小文件大小,若是小於該大小,不會自動重寫。

來實驗一下重寫的結果,咱們先設定一個a值,而後自增屢次,查看AOF文件內容。裏面有不少INCR的語句記錄

而後咱們手動執行下BGREWRITEOF,執行日誌重寫。

能夠看到,多個incr語句,變成了一個 set a 6語句,減小了5個 incr a語句的操做日誌。

AOF優缺點

優勢:

  1. AOF能夠設置 徹底不一樣步、每秒同步、每次操做同,默認是每秒同步。由於AOF是操做指令的追加,因此能夠頻繁的大量的同步。
  2. AOF文件是一個值追加日誌的文件,即便服務宕機爲寫入完整的命令,也能夠經過redis-check-aof工具修復這些問題。
  3. 若是AOF文件過大,Redis會在後臺自動地重寫AOF文件。重寫後會使AOF文件壓縮到最小所需的指令集。
  4. AOF文件是有序保存數據庫的全部寫入操做,易讀,易分析。即便若是不當心誤操做數據庫,也很容易找出錯誤指令,恢復到某個數據節點。例如不當心FLUSHALL,能夠很是容易恢復到執行命令以前。

缺點

  1. 相同數據量下,AOF的文件一般體積會比RDB大。由於AOF是存指令的,而RDB是全部指令的結果快照。但AOF在日誌重寫後會壓縮一些空間。
  2. 在大量寫入和載入的時候,AOF的效率會比RDB低。由於大量寫入,AOF會執行更多的保存命令,載入的時候也須要大量的重執行命令來獲得最後的結果。RDB對此更有優點。

如何選擇

以上已經基本瞭解過RDB和AOF的使用、基本原理以及對應的優缺點。那麼在實際當中,咱們到底怎麼去選擇用哪一種持久化方式呢?

通常來講,不考慮硬盤大小,最安全的作法是RDB與AOF同時使用,即便AOF損壞沒法修復,還能夠用RDB來恢復數據。

若是Redis的數據在你的服務中並非必要的數據,例如只是當簡單的緩存,沒有緩存也不會形成緩存雪崩。說明數據的安全可靠性並非首要考慮範圍內,那麼單獨只使用RDB就能夠了。

不推薦單獨使用AOF,由於AOF對於數據的恢復載入來講,比RDB慢。而且Redis官方也說明了,AOF有一個罕見的bug。出了問題沒法很好的解決。因此使用AOF的時候,最好仍是有RDB做爲數據備份。

根據官方的意願描述,在將來可能會有一種RDB與AOF相結合的持久化模型。到時Redis持久化就再也不如此麻煩費勁了,咱們拭目以待吧。

更多技術文章、精彩乾貨,請關注
博客:zackku.com
微信公衆號:Zack說碼

相關文章
相關標籤/搜索