Redis 持久化概述

來源:互聯網
上載者:User

Redis 持久化概述
Redis 持久化

Redis 提供了不同持久化範圍的選項:

  • RDB 持久化以指定的時間間隔執行資料集的即時點(point-in-time)快照。
  • AOF 持久化在服務端記錄每次收到的寫操作,在伺服器啟動時會重放,以重建未經處理資料集。命令使用和 Redis 協議一樣的格式以追加的方式來記錄。當檔案太大時 Redis 會在後台重寫日誌。
  • 如果你願意,你可以完全禁止持久化,如果你只是希望你的資料在伺服器運行期間才存在的話。
  • 可以在同一個執行個體上同時支援 AOF 和 RDB。注意,在這種情況下,當 Redis 重啟時,AOF 檔案會被用於重建未經處理資料集,因為它被保證是最完整的資料。

理解 RDB 和 AOF 持久化之間的各自優劣 (trade-offs) 是一件非常重要的事情。讓我們先從 RDB 開始:

RDB 優點
  • RDB 是一種表示某個即時點的 Redis 資料的緊湊檔案。RDB 檔案適合用於備份。例如,你可能想要每小時歸檔最近 24 小時的 RDB 檔案,每天儲存近 30 天的 RDB 快照集。這允許你很容易的恢複不同版本的資料集以容災。
  • RDB 非常適合於災難恢複,作為一個緊湊的單一檔案,可以被傳輸到遠端資料中心,或者是 Amazon S3(可能得加密)。
  • RDB 最大化了 Redis 的效能,因為 Redis 父進程持久化時唯一需要做的是啟動(fork)一個子進程,由子進程完成所有剩餘工作。父進程執行個體不需要執行像磁碟 IO 這樣的操作。
  • RDB 在重啟儲存了大資料集的執行個體時比 AOF 要快。
RDB 缺點

    當你需要在 Redis 停止工作(例如停電)時最小化資料丟失,RDB 可能不太好。你可以配置不同的儲存點(save point)來儲存 RDB 檔案(例如,至少 5 分鐘和對資料集 100 次寫之後,但是你可以有多個儲存點)。然而,你通常每隔 5 分鐘或更久建立一個 RDB 快照集,所以一旦 Redis 因為任何原因沒有正確關閉而停止工作,你就得做好最近幾分鐘資料丟失的準備了。

RDB 需要經常調用 fork()子進程來持久化到磁碟。如果資料集很大的話,fork()比較耗時,結果就是,當資料集非常大並且 CPU 效能不夠強大的話,Redis 會停止服務用戶端幾毫秒甚至一秒。AOF 也需要 fork(),但是你可以調整多久頻率重寫日誌而不會有損(trade-off)持久性(durability)。

AOF 優點
  • 使用 AOF Redis 會更具有可持久性(durable):你可以有很多不同的 fsync 策略:沒有 fsync,每秒 fsync,每次請求時 fsync。使用預設的每秒 fsync 策略,寫效能也仍然很不錯(fsync 是由後台線程完成的,主線程繼續努力地執行寫請求),即便你也就僅僅只損失一秒鐘的寫資料。
  • AOF 日誌是一個追加檔案,所以不需要定位,在斷電時也沒有損壞問題。即使由於某種原因檔案末尾是一個寫到一半的命令(磁碟滿或者其他原因),redis-check-aof 工具也可以很輕易的修複。
  • 當 AOF 檔案變得很大時,Redis 會自動在後台進行重寫。重寫是絕對安全的,因為 Redis 繼續往舊的檔案中追加,使用建立當前資料集所需的最小操作集合來建立一個全新的檔案,一旦第二個檔案建立完畢,Redis 就會切換這兩個檔案,並開始往新檔案追加。
  • AOF 檔案裡麵包含一個接一個的操作,以易於理解和解析的格式儲存。你也可以輕易的匯出一個 AOF 檔案。例如,即使你不小心錯誤地使用 FLUSHALL 命令清空一切,如果此時並沒有執行重寫,你仍然可以儲存你的資料集,你只要停止伺服器,刪除最後一條命令,然後重啟 Redis 就可以。
AOF 缺點
  • 對同樣的資料集,AOF 檔案通常要大於等價的 RDB 檔案。
  • AOF 可能比 RDB 慢,這取決於準確的 fsync 策略。通常 fsync 設定為每秒一次的話效能仍然很高,如果關閉 fsync,即使在很高的負載下也和 RDB 一樣的快。不過,即使在很大的寫負載情況下,RDB 還是能提供能好的最大延遲保證。
  • 在過去,我們經曆了一些針對特殊命令(例如,像 BRPOPLPUSH 這樣的阻塞命令)的罕見 bug,導致在資料載入時無法恢複到儲存時的樣子。這些 bug 很罕見,我們也在測試套件中進行了測試,自動隨機創造複雜的資料集,然後載入它們以檢查一切是否正常,但是,這類 bug 幾乎不可能出現在 RDB 持久化中。為了說得更清楚一點:Redis AOF 是通過遞增地更新一個已經存在的狀態,像 MySQL 或者 MongoDB 一樣,而 RDB 快照集是一次又一次地從頭開始創造一切,概念上更健壯。但是,1)要注意 Redis 每次重寫 AOF 時都是以當前資料集中的真實資料從頭開始,相對於一直追加的 AOF 檔案(或者一次重寫讀取老的 AOF 檔案而不是讀記憶體中的資料)對 bug 的免疫力更強。2)我們還沒有收到一份使用者在真實世界中檢測到崩潰的報告。
該選誰

    通常來說,你應該同時使用這兩種持久化方法,以達到和 PostgreSQL 提供的一樣的資料安全程度。

    如果你很關注你的資料,但是仍然可以接受災難時有幾分鐘的資料丟失,你可以只單獨使用 RDB。

    有很多使用者單獨使用 AOF,但是我們並不鼓勵這樣,因為時常進行 RDB 快照集非常方便於Database Backup,啟動速度也較之快,還避免了 AOF 引擎的 bug。

快照

     預設情況下,Redis 儲存資料集快照到磁碟,名為 dump.rdb 的二進位檔案。你可以設定讓 Redis 在 N 秒內至少有 M 次資料集改動時儲存資料集,或者你也可以手動調用 SAVE 或者 BGSAVE 命令。

     例如,這個配置會讓 Redis 在每個 60 秒內至少有 1000 次鍵改動時自動轉儲資料集到磁碟:

save 60 1000

    這種策略被稱為快照。

如何工作

   每當 Redis 需要轉儲資料集到磁碟時,會發生:

  • Redis 調用 fork()。於是我們有了父子兩個進程。
  • 子進程開始將資料集寫入一個臨時 RDB 檔案。
  • 當子進程完成了新 RDB 檔案,替換掉舊檔案。

   這個方法可以讓 Redis 獲益於寫時複製(copy-on-write)機制。

只追加檔案

    快照並不是非常具有可持久性(durable)。如果你運行 Redis 的電腦停機了,電源線斷了,或者你不小心 kill -9 掉你的執行個體,最近寫入 Redis 的資料將會丟失。儘管這個對一些應用程式來說不是什麼大事,但是也有一些需要完全可持久性(durability)的情境,在這些情境下可能就不合適了。

   只追加檔案是一個替代方案,是 Redis 的完全可持久性策略。在 1.1 版本中就可用了。

   你可以在你的設定檔中開啟 AOF:

   

appendonly yes

從現在開始,每次 Redis 收到修改資料集的命令,將會被追加到 AOF 中。當你重啟 Redis 的時候,就會重放(re-play)AOF 檔案來重建狀態。

日誌重寫

   你可以猜得到,寫操作不斷執行的時候 AOF 檔案會越來越大。例如,如果你增加一個計數器 100 次,你的資料集裡只會有一個鍵儲存這最終值,但是卻有 100 條記錄在 AOF 中。其中 99 條記錄在重建目前狀態時是不需要的。

   於是 Redis 支援一個有趣的特性:在後台重建 AOF 而不影響服務用戶端。每當你發送 BGREWRITEAOF 時,Redis 將會寫入一個新的 AOF 檔案,包含重建當前記憶體中資料集所需的最短命令序列。如果你使用的是 Redis 2.2 的 AOF,你需要不時的運行 BGREWRITEAOF 命令。Redis 2.4 可以自動觸發日誌重寫(查看 Redis 2.4 中的樣本設定檔以獲得更多資訊)。

AOF 持久性如何

   你可以配置多久 Redis 會 fsync 資料到磁碟一次。有三個選項:

  • 每次一個新命令追加到 AOF 檔案中時執行 fsync。非常非常慢,但是非常安全。
  • 每秒執行 fsync。夠快(2.4 版本中差不多和快照一樣快),但是當災難來臨時會丟失 1 秒的資料。
  • 從不執行 fsync,直接將你的資料交到作業系統手裡。更快,但是更不安全。

   建議的(也是預設的)策略是每秒執行一次 fsync。既快,也相當安全。一直執行的策略在實踐中非常慢(儘管在 Redis 2.0 中有所改進),因為沒法讓 fsync 這個操作本身更快。

AOF 損壞了怎麼辦

   有可能在寫 AOF 檔案時伺服器崩潰(crash),檔案損壞後 Redis 就無法裝載了。如果這個發生的話,你可以使用下面的步驟來解決這個問題:

  • 建立 AOF 的一個拷貝用於備份。
  • 使用 Redis 內建的 redis-check-aof 工具來修複原檔案:
  • $ redis-check-aof --fix
  • 使用 diff -u 來檢查兩個檔案有什麼不同。用修複好的檔案來重啟伺服器。
如何工作

日誌重寫採用了和快照一樣的寫時複製機制。下面是過程:

  • Redis 調用 fork()。於是我們有了父子兩個進程。
  • 子進程開始向一個臨時檔案中寫 AOF。
  • 父進程在一個記憶體緩衝區中積累新的變更(同時將新的變更寫入舊的 AOF 檔案,所以即使重寫失敗我們也安全)。
  • 當子進程完成重寫檔案,父進程收到一個訊號,追加記憶體緩衝區到子進程建立的檔案末尾。
  • 搞定!現在 Redis 自動重新命名舊檔案為新的,然後開始追加新資料到新檔案。
如何從 RDB 切換到 AOF

   在 Redis 2.2 及以上版本中非常簡單,也不需要重啟。

  • 備份你最新的 dump.rdb 檔案。
  • 把備份檔案放到一個安全的地方。
  • 發送以下兩個命令:
  • redis-cli config set appendonly yes
  • redis-cli config set save ""
  • 確保你的資料庫含有其包���的相同的鍵的數量。
  • 確保寫被正確的追加到 AOF 檔案。

   第一個 CONFIG 命令開啟 AOF。Redis 會阻塞以產生初始轉儲檔案,然後開啟檔案準備寫,開始追加寫操作。

   第二個 CONFIG 命令用於關閉快照持久化。這一步是可選的,如果你想同時開啟這兩種持久化方法。

   重要:記得編輯你的 redis.conf 檔案來開啟 AOF,否則當你重啟伺服器時,你的配置修改將會丟失,伺服器又會使用舊的配置。

AOF 和 RDB 的相互作用

   Redis 2.4 及以後的版本中,不允許在 RDB 快照集操作運行過程中觸發 AOF 重寫,也不允許在 AOF 重寫運行過程中運行 BGSAVE。這防止了兩個 Redis 後台進程同時對磁碟進行繁重的 IO 操作。

   當在快照啟動並執行過程中,使用者使用 BGREWRITEAOF 顯式請求日誌重寫操作的話,伺服器會回覆一個 OK 狀態代碼,告訴使用者這個操作已經被安排調度,等到快照完成時開始重寫。

   Redis 在同時開啟 AOF 和 RDB 的情況下重啟,會使用 AOF 檔案來重建未經處理資料集,因為通常 AOF 檔案是儲存資料最完整的。

備份資料

   一定要備份你的資料庫。磁碟損壞,雲中執行個體丟失,等等:沒有備份意味著資料丟失的巨大風險。

   Redis 對資料備份非常友好,因為你可以在資料庫運行時拷貝 RDB 檔案:RDB 檔案一旦產生就不會被修改,檔案產生到一個臨時檔案中,當新的快照完成後,將自動使用 rename(2) 原子性的修改檔案名稱為目標檔案。

  這意味著,在伺服器運行時拷貝 RDB 檔案是完全安全的。以下是我們的建議:

  • 建立一個定時任務(cron job),每隔一個小時建立一個 RDB 快照集到一個目錄,每天的快照放在另外一個目錄。
  • 每次定時指令碼運行時,務必使用 find 命令來刪除舊的快照:例如,你可以儲存最近 48 小時內的每小時快照,一到兩個月的內的每天快照。注意命名快照時加上日期時間資訊。
  • 至少每天一次將你的 RDB 快照集傳輸到你的資料中心之外,或者至少傳輸到運行你的 Redis 執行個體的物理機之外。
災難恢複

   在 Redis 中災難恢複基本上就是指備份,以及將這些備份傳輸到外部的多個資料中心。這樣即使一些災難性的事件影響到運行 Redis 和產生快照的主要資料中心,資料也是安全的。

由於許多 Redis 使用者都是啟動階段的屌絲,沒有太多錢花,我們會介紹一些最有意思的災難恢複技術,而不用太多的花銷。

  • Amazon S3 和一些類似的服務是協助你災難恢複系統的一個好辦法。只需要將你的每日或每小時的 RDB 快照集以加密的方式傳輸到 S3。你可以使用 gpg -c 來加密你的資料(以對稱式加密模式)。確保將你的密碼儲存在不同的安全地方(例如給一份到你的組織中的最重要的人)。推薦使用多個儲存服務來改進資料安全。
  • 使用 SCP(SSH 的組成部分)來傳輸你的快照到遠程伺服器。這是一種相當簡單和安全的方式:在遠離你的位置搞一個小的 VPS,安裝 ssh,產生一個無口令的 ssh 用戶端 key,並將其添加到你的 VPS 上的 authorized_keys 檔案中。你就可以自動的傳輸備份檔案了。為了達到好的效果,最好是至少從不同的供應商那搞兩個 VPS。

   要知道這種系統如果沒有正確的處理會很容易失敗。至少一定要確保傳輸完成後驗證檔案的大小 (要匹配你拷貝的檔案),如果你使用 VPS 的話,可以使用 SHA1 摘要。

   你還需要一個某種獨立的警示系統,在某些原因導致的傳輸備份過程不正常時警示。

下面關於Redis的文章您也可能喜歡,不妨參考下:

Ubuntu 14.04下Redis安裝及簡單測試

Redis主從複製基本配置

Redis叢集明細文檔

Ubuntu 12.10下安裝Redis(圖文詳解)+ Jedis串連Redis

Redis系列-安裝部署維護篇

CentOS 6.3安裝Redis

Redis安裝部署學習筆記

Redis設定檔redis.conf 詳解

Redis 的詳細介紹:請點這裡
Redis 的:請點這裡

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.