新手村:Redis進階篇二——持久化

Redis進階篇二——持久化

1. 簡介

持久化即將數據保存到可永久保存的存儲設備中。咱們知道 Redis 爲了保證效率而把數據都緩存在內存中,但當咱們重啓系統或關閉系統後,緩存在內存中的數據都會消失,因此爲了讓有些數據能保留下,Redis 持久化存儲就應運而生。Redis 提供了兩種方式進行持久化,一種是RDB 持久化,另外一種是 AOF(append only file) 持久化,下面咱們逐一介紹。web

2. RDB 持久化

RDB 是 Redis 默認的持久化機制,它的工做原理是把當前內存中的數據生成快照 (snapshot) 的方式寫入磁盤中的二進制文件中,默認的文件名爲 dump.rdb。恢復時將快照文件直接讀到內存中。RDB 有兩種觸發方式,分別是自動觸發和手動觸發。redis

2.1 自動觸發

自動觸發使用 save 相關配置觸發,好比 「save m n」,表示在 m 秒內數據庫存在 n 次修改時,自動觸發BGSAVE (BGSAVE 命令在手動觸發時會介紹)。 Redis 默認配置以下:數據庫

save 900 1      # 在 900 秒內若是至少有 1 個 key 的值變化,則觸發
save 300 10 # 在 300 秒內若是至少有 10 個 key 的值變化,則觸發 save 60 10000 # 在 60 秒內若是至少有 10000 個 key 的值變化,則觸發 複製代碼

當實際操做知足配置的 save 形式時就會進行 RDB 持久化,將當前的數據快照保存。windows

2.2 手動觸發

手動觸發進行 RDB 持久化涉及到兩個 Redis 服務器命令:緩存

  1. SAVE:執行一個同步保存操做,將當前 Redis 實例的全部數據快照以 RDB 文件的形式保存到磁盤中。
  2. BGSAVE:用於在後臺異步保存當前數據庫的數據到磁盤。

SAVE 命令因爲是同步操做,所以會阻塞當前 Redis 服務器知道 RDB 持久化過程完成爲止,對於內存比較大的實例會形成長時間阻塞,不建議在線上環境使用。 BGSAVE 命令會執行 fork 操做建立一個子進程,由子進程完成 RDB 持久化過程,完成後自動結束,阻塞只發生在 fork 過程,通常時間很短。 基本上 Redis 內部的 RDB 操做都是採用 BGSAVE 命令。安全

2.3 RDB 優缺點

RDB 的優勢:服務器

  • RDB 文件是一個緊湊壓縮的二進制文件,它保存了 Redis 在某個時間點的數據,比較適合進行備份和災難恢復。
  • 生成 RDB 文件的過程是由父進程 fork 操做建立的一個子進程完成,父進程仍然能夠接受其餘命令請求,不用進行任何磁盤 IO 操做。
  • 因爲 RDB 文件是二進制文件,所以在恢復數據集時速度更快。

RDB 的缺點:app

  • RDB 沒法作到實時持久化/秒級持久化。由於 BGSAVE 命令須要執行 fork 操做建立子進程,若是頻繁操做必然會佔用大量內存,執行成本太高,反而使性能下降。
  • RDB 文件使用特定二進制格式保存,Redis 版本演進過程當中有多個格式的 RDB 版本,容易出現版本不兼容問題。
  • RDB 是隔一段時間進行備份,若是 Redis 在備份時出現意外宕機,那麼就會失去最後一次快照的數據。

3. AOF 持久化

差異於經過保存數據庫中的鍵值對的 RDB 持久化方式,AOF 持久化是經過保存 Redis 服務器所執行的寫命令來記錄數據庫狀態,重啓時再從新執行 AOF 文件中的命令以完成數據恢復。AOF 的主要做用是解決了數據持久化的實時性,目前已是 Redis 持久化的主流方式。異步

3.1 使用 AOF

Redis 中 AOF 是默認關閉的,使用前要將配置參數 appendonly 改成 yes(5.3 中會涉及一些配置參數,配置文件是安裝目錄下的 redis.windows.conf,參數在 APPEND ONLY FILE 一欄)。AOF 文件的保存文件名經過參數 appendfilename 參數配置,默認是 appendonly.aof。AOF 持久化策略的選擇由 appendfsync 參數進行選擇,有下面幾種:編輯器

  • no:不執行 fsync,由操做系統保證數據同步到磁盤,速度快但不安全。
  • always:每次寫入都執行 fsync,雖然保證數據同步到磁盤,可是效率很低。
  • everysec:默認配置,每秒執行一次 fsync,可能會丟失這 1 秒的數據,但兼顧了安全性和效率,最經常使用的選擇。

3.2 AOF工做流程

AOF 的工做流程操做:命令寫入 (append)、文件同步 (sync)、文件重寫 (rewrite)、重啓加載 (load)。 首先,全部的寫入命令都會被追加到 AOF 緩衝區中,而後 AOF 緩衝區根據對應的持久化策略對磁盤進行文件同步操做。當 AOF 文件的大小超過所設定的重寫閾值時對 AOF 文件進行重寫。當須要重寫時,父進程會進行 fork 操做建立一個子進程,子進程帶有父進程的數據副本,由子進程完成重寫過程,在此期間父進程仍然能夠處理其餘命令。 當咱們重啓 Redis 服務器時,能夠加載 AOF 文件進行數據恢復,流程以下:

持久化
持久化

從上圖咱們也能夠得知,在同時開啓了 RDB 和 AOF 的狀況下,Redis 會優先 AOF 文件的加載。遇到異常時,可使用修復命令 redis-check-aof--fix 進行修復。 在上述流程中,咱們有幾點須要注意與知曉的:

  1. 爲何須要 AOF 緩衝:因爲 Redis 自己是單線程工做的,若是每次都直接把寫入命令追加到 AOF 文件中,那麼此時的性能取決於磁盤的 IO 性能,會下降性能。先寫入 AOF 緩衝區中,咱們還能夠選擇緩衝區同步到磁盤的策略,進一步兼顧安全性和性能。

  2. 爲何須要 AOF 重寫:因爲 AOF 持久化是不斷將寫命令記錄到 AOF 文件中,隨着時間的推移,文件必然會愈來愈大,這樣會增長恢復時的壓力。除此以外,例如一個 key 表示粉絲數,增長粉絲的過程咱們會使用大量自增命令,而實際上在恢復時咱們只須要知道在這段時間內總共增長了多少便可。這個例子也正指明瞭重寫機制的工做原理:AOF 文件重寫並不是是對原文件進行整理,而是直接讀取服務器中現有的鍵值對,而後用一條命令代替記錄中改鍵值對的多條命令操做,生成一個新的文件替換原文件

  3. AOF 重寫觸發機制:AOF 重寫也分自動觸發和手動觸發。

    • 自動觸發涉及兩個配置參數:一個是 auto-aof-rewrite-percent,默認值是 100;另外一個是 auto-aof-rewrite-min-size,默認值是 64MB。按照默認配置,Redis 會記錄上次重寫時 AOF 文件大小,並當目前 AOF 文件是上一次重寫後大小的一倍且文件大於 64MB 時自動觸發。

      auto-aof-rewrite-percent:當目前 AOF 文件大小超過上一次重寫的 AOF 文件大小的百分之幾時進行重寫。 auto-aof-rewrite-min-size:設置容許重寫的最小 AOF 文件大小,避免了文件很小卻知足百分比要求的重寫狀況。

    • 手動觸發直接調用 BGREWRITEAOF 命令。

3.3 AOF 優缺點

AOF 的優勢:

  • 提供了多種同步頻率,即便使用默認的同步頻率每秒同步一次,Redis 最多也就失去 1 秒的數據。
  • AOF 文件使用 Redis 命令追加的形式來構造,即便只能向 AOF 文件寫入命令的片斷,也很容易使用redis-check-aof 工具修正。
  • AOF 文件的格式可讀性較強,能夠爲使用者提供更靈活的處理方式。

AOF 的缺點:

  • 在擁有相同數據的狀況下,AOF 文件一般會比 RDB 文件體積更大。
  • 當 Redis 負載較高的狀況下,RDB 會比 AOD 具備更好的性能保證。
  • RDB 使用快照的形式來持久化整個 Redis 數據,而 AOF 只是將每次執行的命令追加到 AOF 文件中,所以從理論上說,RDB 比 AOF 方式更健壯。官方文檔也指出,AOF 的確也存在一些 BUG,這些 BUG 在RDB 沒有存在。

4. 如何選擇

介紹了 Redis 持久化的兩種方式,那麼咱們在實際中應該如何選擇呢?對於數據庫而言,數據是至關重要的,RDB 相比於 AOF 而言出現異常丟失數據可能會更嚴重,除此以外,選擇 RDB 是更好的,定時生成快照是經常使用的數據庫備份方式,而且 RDB 文件是二進制文件,在恢復數據集時速度更快,使用 RDB 方式也能夠規避 AOF 方式中的一些隱藏 bug。可是在通常狀況下,咱們應該同時開啓兩種持久化方式,而不是單獨使用某一種持久化機制。因爲一般狀況下 AOF 方式保存的數據更具實時性且更完整,所以相比 RDB 文件,Redis 重啓時會優先使用 AOF 文件來恢復數據。

最後吟唱

本文使用 mdnice 排版

相關文章
相關標籤/搜索