首頁 >資料庫 >Redis >淺析RDB和AOF持久化,優缺點是什麼?怎麼選?

淺析RDB和AOF持久化,優缺點是什麼?怎麼選?

青灯夜游
青灯夜游轉載
2022-03-11 10:30:023843瀏覽

這篇文章帶大家聊聊redis中RDB 和 AOF 持久化的原理,它們的優缺點是什麼?分析一下應該用哪一個?希望對大家有幫助!

淺析RDB和AOF持久化,優缺點是什麼?怎麼選?

Redis 提供了RDB 和AOF 兩種持久化方案:

  • ##RDB:產生指定時間間隔內的Redis 記憶體中資料快照,是一個二進位檔案dumpr.rdb

  • #AOF:記錄Redis 除了查詢以外的所有寫命令,並在Redis 服務啟動時,透過重新執行這些命令來還原數據。

RDB 持久化

預設Redis 會以RDB 快照的形式將一段時間內的資料持久化到硬碟,保存成一個

dumpr.rdb 二進位。 【相關推薦:Redis影片教學

工作原理簡單介紹一下

當Redis 需要持久化時,Redis 會fork 一個子進程,子進程將資料寫到磁碟上一個臨時RDB 檔案。當子進程完成寫暫存檔案後,將原來的 RDB 替換掉,這樣的好處就是可以

copy-on-write

當然我們也可以手動執行

savebgsave(非同步)產生 RDB 檔案。

redis.conf 預設設定

save 900  1
save 300  10
save 60  10000

    900秒之內,如果超過1個key被修改,則發起快照儲存;
  • 300秒之內,如果超過10個key被修改,則發起快照保存;
  • ##60秒之內,如果1萬個key被修改,則發起快照保存;

RDB 快照指令在預設情況下, Redis 將資料庫快照保存在名字為dump.rdb 的二進位檔案中。

你可以對 Redis 進行設置, 讓它在「 N 秒內資料集至少有 M 個改動」這一條件被滿足時, 自動儲存一次資料集。

你也可以透過呼叫

SAVE

BGSAVE , 手動讓 Redis 進行資料集儲存操作。 比如說, 以下設定會讓Redis 在滿足「 60 秒內有至少有1000 個鍵被改動」這個條件時, 自動儲存一次資料集:

save 60 1000

這個持久化方式稱為快照(snapshot)。

RDB  建立原則當Redis 需要儲存dump.rdb 檔案時, 伺服器執行下列操作:

#Redis 呼叫fork() ,同時擁有父行程和子程序。
  • 子程序將資料集寫入到一個暫存 RDB 檔案中。
  • 當子程序完成對新 RDB 檔案的寫入時,Redis 會用新 RDB 檔案取代原來的 RDB 文件,並刪除舊的 RDB 檔案。
  • 這種運作方式使得 Redis 可以從寫時複製(copy-on-write)機制中獲益。

RDB 的優點RDB 是一個比較緊湊的文件,它保存了Redis 在某個時間點的數據,這種數據比較適合做備份和用於災難復原。

比如說,你可以在最近的 24 小時內,每小時備份一次 RDB 文件,並且在每個月的每一天,也備份一個 RDB 文件。這樣的話,即使遇上問題,也可以隨時將資料集還原到不同的版本。

RDB 的缺點如果你需要盡量避免在伺服器故障時遺失數據,那麼 RDB 不適合你。雖然 Redis 允許你設定不同的保存點來控制保存 RDB 檔案的頻率, 但是, 因為 RDB 檔案需要保存整個資料集的狀態, 所以它並不是一個輕鬆的操作。因此你可能會至少 5 分鐘才儲存一次 RDB 檔案。在這種情況下, 一旦發生故障停機, 你就可能會遺失好幾分鐘的資料。

AOF 持久化

使用AOF 做持久化,每個寫指令都透過

write

函數追加到appendonly.aof 檔案中。 AOF 可以做到全程持久化,只需要在設定檔中開啟(預設為no ),

appendfsync yes

開啟AOF 之後,Redis 每執行一個修改資料的指令,都會把它加入AOF 檔案中,當Redis 重新啟動時,將會讀取AOF 檔案進行「重播」以恢復到Redis 關閉前的最後時刻。

AOF 的設定你可以設定 Redis 多久才將資料 fsync 到磁碟一次。

redis.conf 預設配置

appendfsync yes
appendfsync always     #每次有数据修改发生时都会写入AOF文件。
appendfsync everysec   #每秒钟同步一次,该策略为AOF的缺省策略。

有三個選項:

1,每次有新指令追加到 AOF 檔案時就執行一次 fsync :非常慢,也非常安全。
2,每秒 fsync 一次:夠快(和使用 RDB 持久化差不多),而且在故障時只會遺失 1 秒鐘的資料。
3,從不 fsync :將資料交給作業系統來處理。更快,也更不安全的選擇。

建議(而且也是預設)的措施是每秒 fsync 一次, 這種 fsync 策略可以兼顧速度和安全性。

AOF 創建原則

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

以下是 AOF 重寫的執行步驟

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

子程序開始將新 AOF 檔案的內容寫入到暫存檔案。

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

當子進程完成重寫工作時,它會給父進程發送一個訊號,父進程在接收到訊號之後,將記憶體快取中的所有資料追加到新 AOF 檔案的末尾。

搞定!現在 Redis 原子地用新文件取代舊文件,之後所有指令都會直接追加到新 AOF 文件的最後。

AOF 的優點

1,使用AOF 做持久化,可以設定不同的fsync 策略,例如無fsync ,每秒鐘一次fsync ,或每次執行寫入指令時fsync 。

AOF 的預設策略為每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的效能,並且就算發生故障停機,也最多只會遺失一秒鐘的資料。

fsync 會在後台執行緒執行,所以主執行緒可以繼續努力地處理指令請求。

2,AOF 文件是一個只進行追加操作的日誌文件,不是產生新的之後替換掉那種,即使日誌因為某些原因而包含了未寫入完整的命令(例如寫入時磁碟已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。

3,Redis 可以在 AOF 檔案體積變得過大時,自動地在後台對 AOF 進行重寫: 重寫後的新 AOF 檔案包含了恢復目前資料集所需的最小命令集合。

整個重寫操作是絕對安全的,因為Redis 重寫是創建新AOF 文件,重寫的過程中會繼續將命令追加到現有舊的AOF 文件裡面,即使重寫過程中發生停機,現有舊的AOF 檔案也不會遺失。而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。

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

AOF 的缺點

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

根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB。在一般情況下, 每秒 fsync 的效能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負載之下也是如此。

不過在處理龐大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)。

RDB 和AOF 二者的差異

RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,實際操作過程是fork一個子進程,先將資料集寫入暫存文件,寫入成功後,再取代之前的文件,用二進位壓縮儲存。

AOF持久化以日誌的形式記錄伺服器所處理的每一個寫入、刪除操作,查詢操作不會記錄,以文字的方式追加記錄,可以開啟檔案看到詳細的操作記錄。

RDB 和 AOF 我該用哪一個?

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

AOF 將 Redis 執行的每個指令追加到磁碟中,處理巨大的寫入會降低 Redis 的效能,不知道你是否可以接受。

資料庫備份與災難復原:

定時產生 RDB 快照(snapshot)非常方便進行資料庫備份, 且 RDB 復原資料集的速度也要比 AOF 復原的速度要快。

Redis 支援同時開啟 RDB 和 AOF,系統重啟後,Redis 會優先使用 AOF 來恢復數據,這樣遺失的資料會最少。

AOF BGREWRITEAOF 重寫

因為AOF 的運作方式是不斷地將命令追加到文件的末尾, 所以隨著寫入命令的不斷增加, AOF 文件的體積也會越來越大。

舉例

如果你對計數器呼叫了100 次INCR , 那麼只是為了保存這個計數器的目前值, AOF 檔案就需要使用100 筆記錄(entry)

然而在實際上, 只使用一條 SET 指令已經足以保存計數器的目前值了, 其餘 99 筆記錄其實都是多餘的。

為了處理這種情況, Redis 支援一個有趣的特性: 可以在不打斷服務客戶端的情況下, 對 AOF 檔案進行重建(rebuild)。

執行 BG REWRITE AOF 指令, Redis 將產生一個新的 AOF 文件, 這個文件包含重建目前資料集所需的最少指令。

Redis 2.2 需要自行手動執行 BGREWRITEAOF 指令; Redis 2.4 則可以自動觸發 AOF 重寫, 具體資訊請查看 2.4 的範例設定檔。

備份 Redis 資料

磁碟故障, 節點失效, 諸如此類的問題都可能讓你的資料消失不見, 不進行備份是非常危險的。

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

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

以下是我們的建議

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

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

3,至少每天一次, 將 RDB 備份到你的資料中心之外, 或至少備份到你執行 Redis 伺服器的實體機器之外。

更多程式相關知識,請造訪:程式設計影片! !

以上是淺析RDB和AOF持久化,優缺點是什麼?怎麼選?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除