天天看點

Redis兩種持久化方式AOF和RDB對比

提示:這是我的個人IT資源網站,所有資源都免費,注冊登入後就可以看到密碼,需要什麼大家盡情選取!

今天我們來看看Redis的持久化,如果隻是把Redis作為緩存,在系統啟動的時候,從其他地方加載資料到Redis,是沒有必要考慮持久化的問題,但是有時候我們的業務可能需要将一部分實時資料存在Redis中,而且這些資料是需要在系統中一直顯示的,那麼持久化就很重要了,因為一旦Redis關閉,記憶體中資料就不存在了,那麼在重新啟動後,我們就無法看到資料,但是做了持久化之後,我們可以把持久化資料在啟動的時候重新加載到Redis中,這樣就避免了資料的丢失,下面我們來詳細看一下Redis的持久化是怎麼回事。

RDB

在指定的時間間隔内将記憶體中的資料集快照寫入磁盤,也就是行話講的Snapshot快照,它恢複時是将快照檔案直接讀到記憶體裡,Redis會單獨建立fork一個子程序來進行持久化,會先将資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。整個過程中,主程序是不進行任何IO操作的,這就確定了極高的性能,如果需要進行大規模資料的恢複,且對于資料恢複的完整性不是非常敏感,那麼RDB方式要比AOF方式更加的高效,RDB的缺點是最後一次持久化後的資料可能丢失。

  1. Fork的作用是複制一個與目前程序一樣的程序。新程序的所有資料(變量、環境變量、程式計數器等)數值都和原程序一緻,但是是一個全新的程序,并作為原程序的子程序。
  2. Rdb儲存的是dump.rdb檔案,檔案路徑可以在redis.conf中配置,預設為目前路徑。
  3. 觸發條件在redis.conf中,可以自己設定,例如n秒内修改了m次為觸發條件,一旦觸發條件,則會覆寫之前生成的dump.rdb檔案,最好是定期備份dump.rdb檔案,因為一旦記憶體資料丢失,覆寫了dump.rdb檔案,而且我們又沒有備份檔案,那麼資料就徹底丢失了,雖然備份的檔案的資料不一定是最新的,但是也可以減少損失。
  4. 通過save或者bgsave指令,都可以立即生成dump.rdb檔案,但是save指令是在主程序上進行操作的,會造成堵塞,隻有完成備份,用戶端才能連接配接redis,bgsave指令則是fork(派生)一個save的子程序,不會影響主程序的工作。
  5. RDB是一個非常緊湊的檔案
  6. RDB在儲存RDB檔案時父程序唯一需要做的就是fork出一個子程序,接下來的工作全部由子程序來做,父程序不需要再做其他IO操作,是以RDB持久化方式可以最大化redis的性能。
  7. 與AOF相比,在恢複大的資料集的時候,RDB方式會更快一些。
  8. 資料丢失風險大
  9. RDB需要經常fork子程序來儲存資料集到硬碟上,當資料集比較大的時候,fork的過程是非常耗時的,可能會導緻Redis在一些毫秒級不能響應用戶端請求。

AOF

以日志的形式來記錄每個寫操作,将Redis執行過的所有寫指令記錄下來(讀操作不記錄),隻許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新建構資料,換言之,redis重新開機的話就根據日志檔案的内容将寫指令從前到後執行一次以完成資料的恢複工作。

  1. 當redis.conf的appendonly為yes,生成aof檔案,在重新開機的時候redis會優先加載aof檔案。
  2. 當aof檔案中有不符合redis文法的内容時,我們可以執行redis-check-aof --fix aof檔案,來檢查并清除不符合文法的内容。
  3. appendfsync寫入磁盤的政策,always:同步持久化,每次發生資料變更會被立即記錄到磁盤,性能較差但資料完整性比較好;everysec:出廠預設推薦,異步操作,每秒記錄,如果一秒當機,有資料丢失,no:Redis不會主動調用fsync去将AOF日志内容同步到磁盤,是以這一切就完全依賴于作業系統的調試了。對大多數Linux作業系統,是每30秒進行一次fsync,将緩存區中的資料寫到磁盤上。
  4. 重寫是什麼,AOF采用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制,當AOF檔案的大小超過所設定的門檻值時,Redis就會啟動AOF檔案的内容壓縮,隻保留可以恢複資料的最小指令集,可以使用指令bgrewriteaof。
  5. 重寫原理,AOF檔案持續增長而過大時,會fork出一條新程序來将檔案重寫(也是先寫臨時檔案最後再rename),周遊新程序的記憶體中資料,每條記錄有一條的Set語句。重寫aof檔案的操作,并沒有讀取舊的aof檔案,而是将整個記憶體中的資料庫内容用指令的方式重寫了一個新的aof檔案,這點和快照有點類似。
  6. 重寫觸發機制,Redis會記錄上次重寫時的AOF大小,預設配置是當AOF檔案大小是上次rewrite後大小的一倍且檔案大于64M時觸發。
  7. no-appendfsync-on-rewrite:重寫時是否可以運用appendfsync,用預設no即可,保證資料安全性。
  8. auto-aof-rewrite-min-size:設定重寫的基準值,大小大于多少,auto-aof-rewrite-percentage:設定重寫的基準值,是上次重寫的多少倍,兩者同時滿足時觸發。
  9. 劣勢:相同資料集的資料而言aof檔案要遠大于rdb檔案,恢複速度慢于rdb,aof運作效率要慢于rdb,每秒同步政策效率較好,不同步效率和rdb相同。
  10. aof檔案是一個隻進行追加的日志檔案。
  11. Redis可以在aof檔案體積變得過大時,自動地在背景對aof進行重寫。
  12. aof檔案有序地儲存了對資料庫執行的所有寫入操作,這些寫入操作以Redis協定的格式儲存,是以aof檔案的内容非常容易被人讀懂,對檔案進行分析也很輕松。
  13. 對于相同的資料集來說,aof檔案的體積通常要大于rdb檔案的體積。
  14. 根據所使用的fsync政策,aof的速度可能慢于rdb。

總結:

1.RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照存儲。

2.AOF持久化方式記錄每次對伺服器寫的操作,當伺服器重新開機的時候會重新執行這些指令來恢複原始的資料,AOF指令以redis協定追加儲存每次寫的操作到檔案末尾,Redis還能對AOF檔案進行背景重寫,使得AOF檔案的體積不至于過大。

3.隻做緩存:如果你隻希望你的資料在伺服器運作的時候存在,你也可以不使用任何持久化方式。

4.同時開啟兩種持久化方式,在這種情況下,當redis重新開機的時候會優先載入aof檔案來恢複原始的資料,因為在通常情況下aof檔案儲存的資料集要比rdb檔案儲存的資料集要完整。rdb的資料不實時,同時使用兩者時伺服器重新開機也隻會找aof檔案,那要不要隻使用aof呢?作者建議不要,因為rdb更适合用于備份資料庫(aof在不斷變化不好備份),快速重新開機,而且不會有aof可能潛在的bug,留着作為一個萬一的手段。

建議:

1.因為rdb檔案隻用作後備用途,建議隻在Slave上持久化rdb檔案,而且隻要15分鐘備份一次就夠了,隻保留save 900 1這條規則。

2.如果使用aof,好處是在最惡劣情況下也隻會丢失不超過兩秒資料,啟動腳本較簡單隻load自己的aof檔案就可以了。代價一是帶來了持續的IO,二是aof rewrite的最後将rewrite過程中産生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。隻要硬碟許可,應該盡量減少aof rewrite的頻率,aof重寫的基礎大小預設值64M太小了,可以設到5G以上。預設超過原大小100%大小時重寫可以改到适當的數值。

3.如果不使用aof,僅靠Master-Slave Replication實作高可用性也可以。能省掉一大筆IO也減少了rewrite時帶來的系統波動。代價是如果Master/Slave同時倒掉,會丢失十幾分鐘的資料,啟動腳本也要比較兩個Master/Slave中的rdb檔案,載入較新的那個,新浪微網誌就選用了這種架構。