[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

夜幕鎮嶽丨韋世東發表於2018-10-21

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
Redis 是一個開源( BSD 許可)的,記憶體中的資料結構儲存系統,它可以用作資料庫、快取和訊息中介軟體。它支援的資料型別很豐富,如字串、連結串列、集 合、以及雜湊等,並且還支援多種排序功能。

什麼叫持久化?

用一句話可以將持久化概括為:將資料(如記憶體中的物件)儲存到可永久儲存的儲存裝置中。持久化的主要應用是將記憶體中的物件儲存在資料庫中,或者儲存在磁碟檔案中、 XML 資料檔案中等等。

從應用層與系統層理解持久化

同時,也可以從應用層和系統層這兩個層面來理解持久化:

應用層:如果關閉( Close )你的應用然後重新啟動則先前的資料依然存在。

系統層:如果關閉( Shutdown )你的系統(電腦)然後重新啟動則先前的資料依然存在。

Redis 為什麼要持久化?

Redis 中的資料型別都支援 push/pop、add/remove 及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,Redis 支援各種不同方式的排序。與 Memcached 一樣,為了保證效率,資料都是快取在記憶體中。

對,資料都是快取在記憶體中的,當你重啟系統或者關閉系統後,快取在記憶體中的資料都會消失殆盡,再也找不回來了。所以,為了讓資料能夠長期儲存,就要將 Redis 放在快取中的資料做持久化儲存。

Redis 怎麼實現持久化?

在設計之初,Redis 就已經考慮到了這個問題。官方提供了多種不同級別的資料持久化的方式:

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

2、AOF持久化方式記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些命令來恢復原始的資料,AOF命令以redis協議追加儲存每次寫的操作到檔案末尾.Redis還能對AOF檔案進行後臺重寫,使得AOF檔案的體積不至於過大。

3、如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化方式。

4、你也可以同時開啟兩種持久化方式, 在這種情況下, 當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整。

如果你不知道該選擇哪一個級別的持久化方式,那我們就先來了解一下 AOF 方式和 RDB 方式有什麼樣的區別,並且它們各自有何優劣,學習完之後,再來考慮該選擇哪一種級別。

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

RDB 方式與 AOF 方式的優勢對比

首先我們來看一看官方對於兩種方式的優點描述,並做個對比,然後再看一看兩種方式的缺點描述。

RDB 方式的優點

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

  • RDB 是一個非常緊湊的檔案,它儲存了某個時間點的資料集,非常適用於資料集的備份,比如你可以在每個小時報儲存一下過去24小時內的資料,同時每天儲存過去30天的資料,這樣即使出了問題你也可以根據需求恢復到不同版本的資料集。

  • RDB 是一個緊湊的單一檔案,很方便傳送到另一個遠端資料中心,非常適用於災難恢復。

  • RDB 在儲存 RDB 檔案時父程式唯一需要做的就是 fork 出一個子程式,接下來的工作全部由子程式來做,父程式不需要再做其他 IO 操作,所以 RDB 持久化方式可以最大化 Redis 的效能。

  • 與AOF相比,在恢復大的資料集的時候,RDB 方式會更快一些。

當 Redis 需要儲存 dump.rdb 檔案時, 伺服器執行以下操作:

  • Redis 呼叫forks. 同時擁有父程式和子程式。
  • 子程式將資料集寫入到一個臨時 RDB 檔案中。
  • 當子程式完成對新 RDB 檔案的寫入時,Redis 用新 RDB 檔案替換原來的 RDB 檔案,並刪除舊的 RDB 檔案。

這種工作方式使得 Redis 可以從寫時複製(copy-on-write)機制中獲益。

AOF 方式的優點

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
使用AOF 會讓你的Redis更加耐久:

  • 你可以使用不同的 fsync 策略:無 fsync、每秒 fsync 、每次寫的時候 fsync .使用預設的每秒 fsync 策略, Redis 的效能依然很好( fsync 是由後臺執行緒進行處理的,主執行緒會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的資料。

  • AOF檔案是一個只進行追加的日誌檔案,所以不需要寫入seek,即使由於某些原因(磁碟空間已滿,寫的過程中當機等等)未執行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題。

  • Redis 可以在 AOF 檔案體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢復當前資料集所需的最小命令集合。 整個重寫操作是絕對安全的,因為 Redis 在建立新 AOF 檔案的過程中,會繼續將命令追加到現有的 AOF 檔案裡面,即使重寫過程中發生停機,現有的 AOF 檔案也不會丟失。 而一旦新 AOF 檔案建立完畢,Redis 就會從舊 AOF 檔案切換到新 AOF 檔案,並開始對新 AOF 檔案進行追加操作。

  • AOF 檔案有序地儲存了對資料庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式儲存, 因此 AOF 檔案的內容非常容易被人讀懂, 對檔案進行分析(parse)也很輕鬆。 匯出(export) AOF 檔案也非常簡單: 舉個例子, 如果你不小心執行了 FLUSHALL 命令, 但只要 AOF 檔案未被重寫, 那麼只要停止伺服器, 移除 AOF 檔案末尾的 FLUSHALL 命令, 並重啟 Redis , 就可以將資料集恢復到 FLUSHALL 執行之前的狀態。

優點對比總結

RDB 方式可以儲存過去一段時間內的資料,並且儲存結果是一個單一的檔案,可以將檔案備份到其他伺服器,並且在回覆大量資料的時候,RDB 方式的速度會比 AOF 方式的回覆速度要快。

AOF 方式預設每秒鐘備份1次,頻率很高,它的操作方式是以追加的方式記錄日誌而不是資料,並且它的重寫過程是按順序進行追加,所以它的檔案內容非常容易讀懂。可以在某些需要的時候開啟 AOF 檔案對其編輯,增加或刪除某些記錄,最後再執行恢復操作。

RDB 方式與 AOF 方式的缺點對比

RDB 方式的缺點

  • 如果你希望在 Redis 意外停止工作(例如電源中斷)的情況下丟失的資料最少的話,那麼 RDB 不適合你.雖然你可以配置不同的save時間點(例如每隔 5 分鐘並且對資料集有 100 個寫的操作),是 Redis 要完整的儲存整個資料集是一個比較繁重的工作,你通常會每隔5分鐘或者更久做一次完整的儲存,萬一在 Redis 意外當機,你可能會丟失幾分鐘的資料。

  • RDB 需要經常 fork 子程式來儲存資料集到硬碟上,當資料集比較大的時候, fork 的過程是非常耗時的,可能會導致 Redis 在一些毫秒級內不能響應客戶端的請求。如果資料集巨大並且 CPU 效能不是很好的情況下,這種情況會持續1秒, AOF 也需要 fork ,但是你可以調節重寫日誌檔案的頻率來提高資料集的耐久度。

AOF 方式的缺點

  • 對於相同的資料集來說,AOF 檔案的體積通常要大於 RDB 檔案的體積。

  • 根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在一般情況下, 每秒 fsync 的效能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)。

缺點對比總結

RDB 由於備份頻率不高,所以在回覆資料的時候有可能丟失一小段時間的資料,而且在資料集比較大的時候有可能對毫秒級的請求產生影響。

AOF 的檔案提及比較大,而且由於儲存頻率很高,所以整體的速度會比 RDB 慢一些,但是效能依舊很高。

工作原理

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
AOF 重寫和 RDB 建立快照一樣,都巧妙地利用了寫時複製機制:

  • Redis 執行 fork() ,現在同時擁有父程式和子程式。
  • 子程式開始將新 AOF 檔案的內容寫入到臨時檔案。
  • 對於所有新執行的寫入命令,父程式一邊將它們累積到一個記憶體快取中,一邊將這些改動追加到現有 AOF 檔案的末尾,這樣樣即使在重寫的中途發生停機,現有的 AOF 檔案也還是安全的。
  • 當子程式完成重寫工作時,它給父程式傳送一個訊號,父程式在接收到訊號之後,將記憶體快取中的所有資料追加到新 AOF 檔案的末尾。
  • 現在 Redis 原子地用新檔案替換舊檔案,之後所有命令都會直接追加到新 AOF 檔案的末尾。

付諸實踐,RDB 與 AOF 的實現

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

RDB 方式持久化的開啟與配置

Redis 預設的持久化方式是 RDB ,並且預設是開啟的。RDB 的儲存有方式分為主動儲存與被動儲存。主動儲存可以在 redis-cli 中輸入 save 即可;被動儲存需要滿足配置檔案中設定的觸發條件,目前官方預設的觸發條件可以在 redis.conf 中看到:

save 900 1
save 300 10
save 60 10000
複製程式碼

其含義為:

伺服器在900秒之內,對資料庫進行了至少1次修改
伺服器在300秒之內,對資料庫進行了至少10次修改。
伺服器在60秒之內,對資料庫進行了至少10000次修改。
複製程式碼

滿足觸發條件後,資料就會被儲存為快照,正是因為這樣才說 RDB 的資料完整性是比不上 AOF 的。

觸發儲存條件後,會在指定的目錄生成一個名為 dump.rdb 的檔案,等到下一次啟動 Redis 時,Redis 會去讀取該目錄下的 dump.rdb 檔案,將裡面的資料恢復到 Redis。

這個目錄在哪裡呢?

我們可以在客戶端中輸入命令config get dir檢視:

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

gannicus@$ src/redis-cli
127.0.0.1:6379> config get dir
1) "dir"
2) "/home/gannicus/Documents/redis-5.0.0"
127.0.0.1:6379> 
複製程式碼

返回結果中的"/home/gannicus/Documents/redis-5.0.0"就是存放 dump.rdb 的目錄。

Redis 版本說明

在測試之前,說明一下前提。redis 是直接從官網下載的壓縮包,解壓後得到的 redis-x.x.x 資料夾,比如我的是 redis-5.0.0,然後進入資料夾,在 redis-5.0.0 專案根目錄使用make命令安裝。

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

RDB 被動觸發儲存測試

剛才提到它分為主動儲存與被動觸發,現在我們來測試一下被動觸發。首先啟動 redis-server,然後再開啟客戶端 redis-cli ,先增添幾條記錄:

127.0.0.1:6379> set lca 1
OK
127.0.0.1:6379> set lcb 1
OK
127.0.0.1:6379> set lcc 1
OK
127.0.0.1:6379> set lcd 1
OK
127.0.0.1:6379> set lce 1
OK
127.0.0.1:6379> set lcf 1
OK
127.0.0.1:6379> set lcg 1
OK
127.0.0.1:6379> set lch 1
OK
127.0.0.1:6379> set lci 1
OK
127.0.0.1:6379> set lcj 1
OK
127.0.0.1:6379> set lck 1
OK
127.0.0.1:6379> set lcl 1
OK
127.0.0.1:6379> set lcm 1
OK
複製程式碼

可以看到,總共新增了 13 條記錄:

127.0.0.1:6379> keys *
 1) "lca"
 2) "lcd"
 3) "lcg"
 4) "lce"
 5) "lcb"
 6) "lcm"
 7) "lcf"
 8) "lci"
 9) "lcl"
10) "lcc"
11) "lck"
12) "lcj"
13) "lch"
127.0.0.1:6379> 
複製程式碼

然後發現redis-server端的日誌視窗中出現瞭如下的提示:

21971:M 21 Oct 2018 16:52:44.062 * 10 changes in 300 seconds. Saving...
21971:M 21 Oct 2018 16:52:44.063 * Background saving started by pid 22552
22552:C 21 Oct 2018 16:52:44.066 * DB saved on disk
21971:M 21 Oct 2018 16:52:44.165 * Background saving terminated with success
複製程式碼

從英文提示中可以大概讀懂這些內容,它檢測到 300 秒內有 10 條記錄被改動,剛才我們新增了 13 條資料記錄,滿足 redis.conf 中對於 RDB 資料儲存的條件,所以這裡執行資料儲存操作,並且提示開闢了一個 22552 的程式出來執行儲存操作,最後提示儲存成功。

並且在目錄內看到有 dump.rdb 檔案生成。

現在將redis程式kill,哪些資料會被儲存?

通過命令 kill -9 pid ( pid 是程式編號)模擬 Redis 異常關閉,然後再啟動 Redis ,我們來看一看,到底是隻儲存了 10 條記錄還是 13 條全都儲存下來了?

127.0.0.1:6379> keys *
 1) "lcb"
 2) "lcj"
 3) "lcd"
 4) "lch"
 5) "lci"
 6) "lcc"
 7) "lcf"
 8) "lce"
 9) "lca"
10) "lcg"
127.0.0.1:6379> 
複製程式碼

重啟後檢視記錄,發現 13 條記錄中只有 10 條記錄會被儲存,這也印證了之前所說,RDB 方式的資料完整性是不可靠的,除非斷掉的那一刻正好是滿足觸發條件的條數。

關閉 RDB

剛才提到了,它是預設啟用的,如果你不需要它可以在配置檔案中將這 3 個配置註釋掉,並新增 save ""即可:

  save ""
# save 900 1
# save 300 10
# save 60 10000
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
儲存配置檔案後需要重新啟動 Redis 服務才會生效,然後繼續新增十幾條記錄:

127.0.0.1:6379> keys *
 1) "lcb"
...
23) "lca"
24) "lcg"
127.0.0.1:6379> 
複製程式碼

在之前已有 10 條的基礎上我再增加了 14 條記錄,這次同樣要通過kill來模擬 Redis 異常關閉,再啟動服務看一看,資料是否還被儲存:

127.0.0.1:6379> keys *
 1) "lcb"
 2) "lcj"
 3) "lcd"
 4) "lch"
 5) "lci"
 6) "lcc"
 7) "lcf"
 8) "lce"
 9) "lca"
10) "lcg"
127.0.0.1:6379> 
複製程式碼

發現後面新增的 14 條記錄並沒有被儲存,恢復資料的時候僅僅只是恢復了之前的 10 條。並且觀察 Redis 服務端視窗日誌,並未發現像之前一樣的觸發儲存的提示,證明 RDB 方式已經被關閉。

RDB 主動儲存測試

通過配置檔案關閉被動觸發,那麼主動關閉是否還會生效呢?

在 Redis 客戶端( redis-cli )通過del命令刪除幾條記錄,然後輸入save命令執行儲存操作:

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

127.0.0.1:6379> keys *
 1) "lcc"
 2) "lch"
 3) "lcb"
 4) "lci"
 5) "lce"
 6) "lcj"
 7) "lcg"
 8) "lca"
 9) "lcd"
10) "lcf"
127.0.0.1:6379> del lca lcb lcc
(integer) 3
127.0.0.1:6379> save
OK
127.0.0.1:6379> 
複製程式碼

可以看到redis-server的日誌有新的提示:22598:M 21 Oct 2018 17:22:31.365 * DB saved on disk,它告訴我們資料已經儲存。

那麼繼續模擬異常關閉,再開啟服務,看一看是否真的儲存了這些操作:

127.0.0.1:6379> keys *
1) "lci"
2) "lcj"
3) "lcd"
4) "lcg"
5) "lcf"
6) "lce"
7) "lch"
127.0.0.1:6379> 
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
果不其然,這幾個刪除操作都被儲存了下來,恢復過來的資料中已經沒有那 3 條記錄了,證明主動關閉不受 配置檔案的影響。

除了save還有其他的儲存方式麼?

save 和 bgsave 儲存

有的,Redis 提供了savebgsave這兩種不同的儲存方式,並且這兩個方式在執行的時候都會呼叫rdbSave函式,但它們呼叫的方式各有不同:

  • save 直接呼叫 rdbSave方法 ,阻塞 Redis 主程式,直到儲存完成為止。在主程式阻塞期間,伺服器不能處理客戶端的任何請求。

  • bgsave 則 fork 出一個子程式,子程式負責呼叫 rdbSave ,並在儲存完成之後向主程式傳送訊號,通知儲存已完成。因為 rdbSave 在子程式被呼叫,所以 Redis 伺服器在 bgsave 執行期間仍然可以繼續處理客戶端的請求。

save 是同步操作,bgsave 是非同步操作。

bgsave命令的使用方法和save命令的使用方法是一樣的:

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

127.0.0.1:6379> keys *
1) "lci"
2) "lcj"
3) "lcd"
4) "lcg"
5) "lcf"
6) "lce"
7) "lch"
127.0.0.1:6379> del lci lcj 
(integer) 2
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> keys *
1) "lcd"
2) "lcg"
3) "lcf"
4) "lce"
5) "lch"
127.0.0.1:6379> 
複製程式碼

shutdown 儲存

事實上,shutdown命令也是可以儲存資料的,驚不驚喜。它會在關閉前將資料儲存下來,意不意外?

127.0.0.1:6379> set app 1
OK
127.0.0.1:6379> set apps 1
OK
127.0.0.1:6379> keys *
1) "apps"
2) "lcd"
3) "lcg"
4) "lcf"
5) "app"
6) "lce"
7) "lch"
127.0.0.1:6379> shutdown
not connected> quit
gannicus@$ 
複製程式碼

然後 Redis 服務就被關閉掉了。我們需要重新啟動 Redis 服務,到客戶端中看一看是否生效:

gannicus@$ src/redis-cli
127.0.0.1:6379> keys *
1) "lce"
2) "lcf"
3) "lcd"
4) "lch"
5) "lcg"
複製程式碼

竟然沒有生效,刺不刺激?這是為什麼呢?明明官方文件之shutdown就說會儲存了才退出的,你騙人~

注意到,文件中有一句

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

恍然大悟,原來是要在持久化被開啟的情況下,通過shutdown命令關閉才不會丟失資料,那麼就到配置檔案中將那幾個save的配置項開啟吧:

#   save ""
save 900 1
save 300 10
save 60 10000
複製程式碼

然後再開啟 Redis 服務,再嘗試一遍(過程為:新增 -> shutdown -> 重啟服務 -> 檢視):

127.0.0.1:6379> set app 1
OK
127.0.0.1:6379> set apps 1
OK
127.0.0.1:6379> shutdown
not connected> quit
gannicus@$ src/redis-cli
127.0.0.1:6379> keys *
1) "lce"
2) "lch"
3) "app"
4) "lcf"
5) "apps"
6) "lcd"
7) "lcg"
127.0.0.1:6379> 
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
這下終於弄明白了。

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

AOF 方式持久化的開啟與配置

開啟 AOF

預設是不開啟 AOF 的,如果想要啟用則需要到 redis.conf 配置檔案中開啟,開啟 redis.conf:

$ vim redis.conf
複製程式碼

然後在檔案中找到 appendonly 並將 no 改為 yes

appendonly yes
複製程式碼

即為開啟了 AOF 方式的持久化。

設定同步方式

AOF 還有支援幾種同步方式,它們分別是:

appendfsync always  # 每次有資料修改發生時都會寫入AOF檔案(安全但是費時)。
appendfsync everysec  # 每秒鐘同步一次,該策略為AOF的預設策略。
appendfsync no  # 從不同步。高效但是資料不會被持久化。
複製程式碼

預設配置是 everysec,你可以根據需求進行調整,這裡我將配置改成 always

appendfsync always
# appendfsync everysec
# appendfsync no
複製程式碼

自定義 AOF 記錄檔案的檔名

Redis 設定有預設的檔名,在配置中顯示為:

appendfilename "appendonly.aof"
複製程式碼

你可以讓其保持預設名字,也可以指定其他的檔名,比如:

appendfilename "RNGLetme.aof"
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
appendonlyappendfsyncappendfilename設定好並儲存。重新啟動 Redis 服務:

$./redis-server
複製程式碼

通過命令 ls 檢視本地檔案,可以看到新生成了一個名為 RNGLetme.aof 的檔案,可以使用:

$cat RNGLetme.aof  
複製程式碼

來檢視裡面的內容,由於當前未進行資料的改動,所以是空白的。

然後開啟 Redis 的客戶端:

$./redis-cli
複製程式碼

並且新增幾條資料記錄:

127.0.0.1:6379> set rng lpl
OK
127.0.0.1:6379> set ig lpl
OK
127.0.0.1:6379> set edg lpl
OK
127.0.0.1:6379> keys *
1) "edg"
2) "rng"
3) "ig"
127.0.0.1:6379> 
複製程式碼

可以看到,成功新增了 rngedgig 這三條記錄,然後開啟 RNGLetme.aof 檔案,看看裡面的記錄:

*2
$6
SELECT
$1
0
*3
$3
set
$3
rng
$3
lpl
*3
$3
set
$2
ig
$3
lpl
*3
$3
set
$3
edg
$3
lpl
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
每一次的資料新增都被記錄下來了。

那如果是刪除操作呢,也會被記錄下來麼?

127.0.0.1:6379> del edg
(integer) 1
127.0.0.1:6379> keys *
1) "rng"
2) "ig"
127.0.0.1:6379> 
複製程式碼

執行完刪除操作後,再看一看 RNGLetme.aof 檔案中的記錄:

*2
$6
SELECT
$1
0
*3
$3
set
$3
rng
$3
lpl
*3
$3
set
$2
ig
$3
lpl
*3
$3
set
$3
edg
$3
lpl
*2
$3
del
$3
edg
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
對比之前的記錄,新增了del edg的操作記錄。這就印證了之前對 AOF 的描述:以日誌的方式將資料變動記錄下來。

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

AOF 恢復測試

下面同樣是通過 kill 命令模擬 Redis 異常關閉:

gannicus@$ kill -9 22645
複製程式碼

然後再重新啟動 Redis 服務:

$ src/redis-server redis.conf
複製程式碼

接著通過客戶端看一看,那些資料是否都在:

$ src/redis-cli
127.0.0.1:6379> keys *
1) "ig"
2) "rng"
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
可以看到,rngig都還在,意味著持久化是生效的。

怎樣從RDB方式切換為AOF方式

在 Redis 2.2 或以上版本,可以在不重啟的情況下,從 RDB 切換到 AOF :

為最新的 dump.rdb 檔案建立一個備份、將備份放到一個安全的地方。執行以下兩條命令:

redis-cli config set appendonly yes
redis-cli config set save “”
複製程式碼

確保寫命令會被正確地追加到 AOF 檔案的末尾。 執行的第一條命令開啟了 AOF 功能: Redis 會阻塞直到初始 AOF 檔案建立完成為止, 之後 Redis 會繼續處理命令請求, 並開始將寫入命令追加到 AOF 檔案末尾。

執行的第二條命令用於關閉 RDB 功能。 這一步是可選的, 如果你願意的話, 也可以同時使用 RDB 和 AOF 這兩種持久化功能。

重要:別忘了在 redis.conf 中開啟 AOF 功能!否則伺服器重啟後,之前通過 CONFIG SET 命令設定的配置就會被遺忘, 程式會按原來的配置來啟動伺服器。

優先選擇 RDB 還是 AOF 呢?

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

分析對比兩種方式並做了測試後,發現這是兩種不同風格的持久化方式,那麼應該如何選擇呢?

  • 對於企業級的中大型應用,如果不想犧牲資料完整性但是又希望保持高效率,那麼你應該同時使用 RDB 和 AOF 兩種方式;
  • 如果你不打算耗費精力在這個地方,只需要保證資料完整性,那麼優先考慮使用 AOF 方式;
  • RDB 方式非常適合大規模的資料恢復,如果業務對資料完整性和一致性要求不高,RDB是很好的選擇。

備份redis資料的建議

確保你的資料有完整的備份,磁碟故障、節點失效等問題問題可能讓你的資料消失不見, 不進行備份是非常危險的。

Redis 對於資料備份是非常友好的, 因為你可以在伺服器執行的時候對 RDB 檔案進行復制: RDB 檔案一旦被建立, 就不會進行任何修改。 當伺服器要建立一個新的 RDB 檔案時, 它先將檔案的內容儲存在一個臨時檔案裡面, 當臨時檔案寫入完畢時, 程式才使用 rename(2) 原子地用臨時檔案替換原來的 RDB 檔案。

這也就是說,無論何時,複製 RDB 檔案都是絕對安全的。

  • 建立一個定期任務( cron job ), 每小時將一個 RDB 檔案備份到一個資料夾, 並且每天將一個 RDB 檔案備份到另一個資料夾。

  • 確保快照的備份都帶有相應的日期和時間資訊, 每次執行定期任務指令碼時, 使用 find 命令來刪除過期的快照: 比如說, 你可以保留最近 48 小時內的每小時快照, 還可以保留最近一兩個月的每日快照。

  • 至少每天一次, 將 RDB 備份到你的資料中心之外, 或者至少是備份到你執行 Redis 伺服器的物理機器之外。

Redis 密碼持久化

在 Redis 中資料需要持久化,密碼也要持久化。在客戶端通過命令:

config set requirepass zxc9527
複製程式碼

可以為 Redis 設定值為zxc9527的密碼,但是當 Redis 關閉並重新啟動後,許可權驗證功能就會失效,再也不需要密碼。所以,密碼也需要在 redis.conf 中持久化。開啟 redis.conf 找到 requirepass 配置項,取消其註釋並在後面設定密碼:

requirepass zxc9527
複製程式碼

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐
儲存後重啟 Redis 服務,密碼持久化即生效。

[動圖演示]Redis 持久化 RDB/AOF 詳解與實踐

參考文章

相關文章