兩種Redis持久化方式對比

兩種持久化方式

Redis 提供了不同級別的持久化方式:

  • RDB:能夠在指定的時間間隔能對你的數據進行快照存儲。
  • AOF:記錄每次對服務器寫的操作,當服務器重啓的時候會重新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操作到文件末尾。

RDB

優點

  • RDB文件非常適合備份。例如,您可以在最近的24小時內每小時存檔一次RDB文件,並在30天內每天保存一個RDB快照。允許您在發生災難時輕鬆恢復數據集的不同版本
  • RDB是一個緊湊的單一文件,很方便傳送到另一個遠端數據中心,非常適用於災難恢復。
  • RDB在保存RDB文件時父進程唯一需要做的就是fork出一個子進程,接下來的工作全部由子進程來做,父進程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
  • 與AOF相比,在恢復大的數據集的時候,RDB方式會更快一些。

缺點

  • Redis要完整的保存整個數據集是一個比較繁重的工作,通常會每隔5分鐘或者更久做一次完整的保存,萬一在Redis意外宕機,你可能會丟失幾分鐘的數據。
  • RDB 需要經常fork子進程來保存數據集到硬盤上,當數據集比較大的時候,fork的過程是非常耗時的,可能會導致Redis在一些毫秒級內的請求不能響應客戶端。

AOF

優點

  • fsync策略:無fsync,每秒fsync默認且推薦),每次查詢fsync。使用fsync的默認策略,每秒的寫入性能仍然很好。您只可能丟失一秒的寫入操作。
  • AOF文件是一個只進行追加的日誌文件,即使由於某些原因(磁盤空間已滿,寫的過程中宕機等等)未執行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題。
  • 可以在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫:重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操作是絕對安全的,因爲 Redis 在創建新 AOF 文件的過程中,會繼續將命令追加到現有的 AOF 文件裏面,即使重寫過程中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。
  • AOF 文件有序地保存了對數據庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式保存, 因此 AOF 文件的內容非常容易讀懂, 對文件進行分析(parse)也很輕鬆。

缺點

  • 對於相同的數據集來說,AOF 文件的體積通常要大於 RDB 文件的體積。
  • 根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。

如何選擇使用哪種持久化方式?

  • 一般來說, 如果想達到足以媲美 PostgreSQL 的數據安全性, 你應該同時使用兩種持久化功能

  • 如果你非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失, 那麼你可以只使用 RDB 持久化。

  • 不推薦只使用AOF,因爲定時生成 RDB 快照非常便於進行數據庫備份,並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快,還能避免AOF的Bug (在你使用的Redis版本中存在)。

AOF 和 RDB 在未來可能會合並。

RDB的工作過程

當 Redis 需要保存 dump.rdb 文件時, 服務器執行以下操作:

  • Redis 調用forks. 同時擁有父進程和子進程。
  • 子進程將數據集寫入到一個臨時 RDB 文件中。
  • 當子進程完成對新 RDB 文件的寫入時,Redis 用新 RDB 文件替換原來的 RDB 文件,並刪除舊的 RDB 文件。

AOF文件的重寫

因爲 AOF 的運作方式是不斷地將命令追加到文件的末尾, 所以隨着寫入命令的不斷增加, AOF 文件的體積也會變得越來越大。例如, 如果你對一個計數器調用了 100 次 INCR , 那麼僅僅是爲了保存這個計數器的當前值, AOF 文件就需要使用 100 條記錄。然而在實際上, 只使用一條 SET 命令已經足以保存計數器的當前值了, 其餘 99 條記錄實際上都是多餘的。 Redis 2.4 以後可以自動觸發 AOF 重寫。

如果AOF文件損壞了怎麼辦?

服務器可能在程序正在對 AOF 文件進行寫入時停機, 如果停機造成了 AOF 文件出錯, 那麼 Redis 在重啓時會拒絕載入這個 AOF 文件, 從而確保數據的一致性不會被破壞。當發生這種情況時, 可以用以下方法來修復出錯的 AOF 文件:

  • 爲現有的 AOF 文件創建一個備份。
  • 使用 Redis 附帶的 redis-check-aof 程序,對原來的 AOF 文件進行修復。
  • 重啓 Redis 服務器,等待服務器載入修復後的 AOF 文件,並進行數據恢復。

AOF重寫過程

  • Redis 執行 forks ,現在同時擁有父進程和子進程。
  • 子進程開始寫入新的 AOF 文件。
  • 對於所有新執行的寫入命令,父進程一邊將它們累積到一個內存緩存中,一邊將這些改動追加到現有 AOF 文件的末尾,這樣樣即使在重寫的中途發生停機,現有的 AOF 文件也還是安全的。
  • 當子進程完成重寫工作時,它給父進程發送一個信號,父進程在接收到信號之後,將內存緩存中的所有數據追加到新 AOF 文件的末尾。
  • Redis 用新文件替換舊文件(原子操作),之後所有命令都會直接追加到新 AOF 文件的末尾。

備份數據

  • 創建一個定期任務, 每小時將一個 RDB 文件備份到一個文件夾, 並且每天將一個 RDB 文件備份到另一個文件夾。
  • 使用 find 命令來刪除過期的快照。
  • 至少每天一次, 將 RDB 備份到你的數據中心之外, 或者至少是備份到你運行 Redis 服務器的物理機器之外。

參考

[1] Redis Persistence.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章