Redis(二)、數據的持久化

Redis數據持久化

第1章 Redis持久化

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

q  RDB 持久化可以在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。

q  AOF 持久化記錄服務器執行的所有寫操作命令,並在服務器啓動時,通過重新執行這些命令來還原數據集。 AOF 文件中的命令全部以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還可以在後臺對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。

q  Redis 還可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, Redis 重啓時, 它會優先使用 AOF 文件來還原數據集, 因爲 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整。

q  你甚至可以關閉持久化功能,讓數據只在服務器運行時存在。

第2章 RD--快照

2.1 RDB的優點

q  RDB 是一個非常緊湊(compact)的文件,它保存了 Redis 在某個時間點上的數據集。 這種文件非常適合用於進行備份: 比如說,你可以在最近的 24 小時內,每小時備份一次 RDB 文件,並且在每個月的每一天,也備份一個 RDB 文件。 這樣的話,即使遇上問題,也可以隨時將數據集還原到不同的版本。

q  RDB 非常適用於災難恢復(disaster recovery):它只有一個文件,並且內容都非常緊湊,可以(在加密後)將它傳送到別的數據中心。

q  RDB 可以最大化 Redis 的性能:父進程在保存 RDB 文件時唯一要做的就是 fork 出一個子進程,然後這個子進程就會處理接下來的所有保存工作,父進程無須執行任何磁盤 I/O 操作。

q  RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。

2.2 RDB的缺點

q  如果你需要儘量避免在服務器故障時丟失數據,那麼 RDB 不適合你。 雖然 Redis 允許你設置不同的保存點(save point)來控制保存 RDB 文件的頻率, 但是, 因爲RDB 文件需要保存整個數據集的狀態, 所以它並不是一個輕鬆的操作。 因此你可能會至少 5 分鐘才保存一次 RDB 文件。 在這種情況下, 一旦發生故障停機, 你就可能會丟失好幾分鐘的數據。

q  每次保存 RDB 的時候,Redis 都要 fork() 出一個子進程,並由子進程來進行實際的持久化工作。 在數據集比較龐大時, fork() 可能會非常耗時,造成服務器在某某毫秒內停止處理客戶端; 如果數據集非常巨大,並且 CPU 時間非常緊張的話,那麼這種停止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也需要進行 fork() ,但無論 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。

2.3 配置RDB快照

2.3.1 快照文件名

在默認的情況下, Redis 將數據庫快照保存在名字爲 dump.rdb 的二進制文件中。這是由參數dbfilename來決定的。

2.3.2 快照保存策略

以對 Redis 進行設置, 讓它在“ N 秒內數據集至少有 M 個改動這一條件被滿足時, 自動保存一次數據集。

比如說, 以下設置會讓 Redis 在滿足“ 60 秒內有至少有 1000 個鍵被改動這一條件時, 自動保存一次數據集:

save 60 1000

默認配置爲:

save 900 1                     
save 300 10
save 60 10000

如果想要關閉快照功能,則只需將以上配置替換爲:

save ""

2.4 RDB快照運作方式

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

  1. Redis調用 fork() ,同時擁有父進程和子進程。

  2. 子進程將數據集寫入到一個臨時 RDB 文件中。

  3. 當子進程完成對新 RDB 文件的寫入時,Redis 用新 RDB 文件替換原來的 RDB 文件,並刪除舊的 RDB 文件。

第3章 AOF--追加

3.1 AOF的優點

q  使用 AOF 持久化會讓 Redis 變得非常耐久(much more durable):你可以設置不同的 fsync 策略,比如無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync  AOF 的默認策略爲每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的性能,並且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync 會在後臺線程執行,所以主線程可以繼續努力地處理命令請求)。

q  AOF 文件是一個只進行追加操作的日誌文件(append only log), 因此對 AOF 文件的寫入不需要進行 seek  即使日誌因爲某些原因而包含了未寫入完整的命令(比如寫入時磁盤已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。

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

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

3.2 AOF的缺點

q  對於相同的數據集來說,AOF 文件的體積通常要大於 RDB 文件的體積。

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

q  AOF 在過去曾經發生過這樣的 bug 因爲個別命令的原因,導致 AOF 文件在重新載入時,無法將數據集恢復成保存時的原樣。 (舉個例子,阻塞命令 BRPOPLPUSH 就曾經引起過這樣的 bug 。) 測試套件裏爲這種情況添加了測試: 它們會自動生成隨機的、複雜的數據集, 並通過重新載入這些數據來確保一切正常。 雖然這種 bug AOF 文件中並不常見, 但是對比來說, RDB 幾乎是不可能出現這種 bug 的。

3.3 配置AOF

3.3.1 AOF功能開啓

通過修改配置文件來打開AOF功能:

appendonly yes


3.3.2 AOF同步策略

我們可以配置 Redis 多久纔將數據 fsync 到磁盤一次。

有三個選項:

q  always

每次有新命令追加到 AOF 文件時就執行一次 fsync :非常慢,也非常安全。

q  everysec

每秒 fsync 一次:足夠快(和使用 RDB 持久化差不多),並且在故障時只會丟失 1 秒鐘的數據。推薦(並且也是默認)的措施爲每秒 fsync 一次, 這種 fsync 策略可以兼顧速度和安全性

q  no

從不 fsync :將數據交給操作系統來處理。更快,也更不安全的選擇。

具體參數如下:

appendfsync everysec


3.3.3 AOF重寫

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

爲了處理這種情況, Redis 支持一種有趣的特性: 可以在不打斷服務客戶端的情況下, AOF 文件進行重建(rebuild)。執行 BGREWRITEAOF 命令, Redis 將生成一個新的 AOF 文件, 這個文件包含重建當前數據集所需的最少命令。

auto-aof-rewrite-percentage 100


#<==觸發自動重寫所佔的百分比,0表示禁用自動重寫功能

auto-aof-rewrite-min-size 64mb


#<==指定自動重寫AOF文件的最小大小

3.3.4 AOF修復錯誤校驗

服務器可能在程序正在對 AOF 文件進行寫入時停機, 如果停機造成了 AOF 文件出錯(corrupt), 那麼 Redis 在重啓時會拒絕載入這個 AOF 文件, 從而確保數據的一致性不會被破壞。

當發生這種情況時, 可以用以下方法來修復出錯的 AOF 文件:

1、爲現有的 AOF 文件創建一個備份。

2、使用 Redis 附帶的 redis-check-aof 程序,對原來的 AOF 文件進行修復。

$ redis-check-aof --fix

3、(可選)使用 diff -u 對比修復後的 AOF 文件和原始 AOF 文件的備份,查看兩個文件之間的不同之處。

4、重啓 Redis 服務器,等待服務器載入修復後的 AOF 文件,並進行數據恢復。

配置參數如下:

aof-load-truncated yes
#<==是否加載被截斷(reids出問題時AOF文件可能被截斷)的AOF日誌。設置yes表示加載被截斷的AOF文件,並通過日誌告知用戶;如果設置爲no,則redis拒絕啓動,需要運行redis-check-aof才能啓動服務。

3.3.5 AOF運作方式

AOF 重寫和 RDB 創建快照一樣,都巧妙地利用了寫時複製機制。

以下是 AOF 重寫的執行步驟:

1Redis 執行 fork() ,現在同時擁有父進程和子進程。

2、子進程開始將新 AOF 文件的內容寫入到臨時文件。

3、對於所有新執行的寫入命令,父進程一邊將它們累積到一個內存緩存中,一邊將這些改動追加到現有 AOF 文件的末尾: 這樣即使在重寫的中途發生停機,現有的 AOF 文件也還是安全的。

4、當子進程完成重寫工作時,它給父進程發送一個信號,父進程在接收到信號之後,將內存緩存中的所有數據追加到新 AOF 文件的末尾。

5、搞定!現在 Redis 原子地用新文件替換舊文件,之後所有命令都會直接追加到新 AOF 文件的末尾。

第4章 RDBAOF之間的切換

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

1、爲最新的 dump.rdb 文件創建一個備份。

2、將備份放到一個安全的地方。

3、執行以下兩條命令:

redis-cli> CONFIG SET appendonly yes
redis-cli> CONFIG SET save ""

4、確保命令執行之後,數據庫的鍵的數量沒有改變。

5、確保寫命令會被正確地追加到 AOF 文件的末尾。

步驟 3 執行的第一條命令開啓了 AOF 功能: Redis 會阻塞直到初始 AOF 文件創建完成爲止, 之後 Redis 會繼續處理命令請求, 並開始將寫入命令追加到 AOF 文件末尾。

步驟 3 執行的第二條命令用於關閉 RDB 功能。 這一步是可選的, 也可以同時使用 RDB AOF 這兩種持久化功能。

注:別忘了在 redis.conf 中打開 AOF 功能! 否則的話, 服務器重啓之後, 之前通過 CONFIG SET 設置的配置就會被遺忘, 程序會按原來的配置來啓動服務器。

 


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