AOF持久化(redis服務器篇)

RDB 持久化的缺點

RDB 持久化,這種持久化可以將數據庫裏面的數據以二進制文件的形式儲存到硬盤裏面。

RDB 持久化有一個缺點,那就是,因 爲創建 RDB 文件需要將服務器所有數據庫的數據都保存起來,這是一個非常耗費資源和時間的操作,所以服務器需要隔一段時間才創建一個新的 RDB 文件,也即是說,創建 RDB 文件的操作不能執行得過於頻繁,否則就會嚴重地影響服務器的性能。

比如說,在 save 配置選項的默認設置下,即使有超過 10000 次修改操作發生,服務器也至少會間隔一分鐘才創建下一個 RDB 文件:
save 900 1
save 300 10
save 60 10000
如果在等待創建下一個 RDB 文件的過程中,服務器遭遇了意外停機,那麼用 戶將丟失最後一次創建 RDB 文件之後,數據庫發生的所有修改。

數據丟失例子

在這裏插入圖片描述

解決方法

爲了解決 RDB 持久化在遭遇意外停機 時丟失大量數據的問題,Redis 提供了 AOF 持久化功能。

比起 RDB 持久化, AOF 持久化有一個巨大的優勢,那就是,用戶可以根據自己的需要對 AOF 持久化進行調整,讓 Redis 在遭遇意外停機時不丟失任何數據,或者只丟失一秒鐘數據,這比 RDB 持久化遭遇意外停機時,丟失的數據要少得多。

AOF 持久化的運作原理

數據保存和數據還原

保存數據

AOF 持久化保存數據庫數據的方法是:每當有修改數據 庫的命令被執行時,服務器就會將被執行的命令寫入到 AOF 文件的末尾。
在這裏插入圖片描述

數據還原

因爲 AOF 文件裏面儲存了服務器執行過的所有數據庫修改命令,所以給定一個 AOF 文件,服務器只要重新執行一遍 AOF 文件裏面包含的所有命令,就可以達到 還原數據庫數據的目的。

舉個例子,對於包含以下內容的 AOF 文件來說:

SELECT 0
SET msg “hello”
INCR counter
SADD alphabets “a” “b” “c”
INCR counter

服務器只要重新執行這些命令,就可以還原出上圖所示的數據庫。

安全性問題

通過配置選項來調整 AOF 持久化的安全性

AOF 持久化的安全性問題

雖然服務器每執行一個修改數據庫的命令,就會將被執行的命令寫入到 AOF 文件,但這並不意味着AOF 持久化不會丟失任何數據。

在目前常見的操作系統中,執行系統調用 write 函數,將一些內容寫入到某個文件裏面 時,爲了提高效率,系統通常不會直接將內容寫入到硬 盤裏面,而是先將內容放入到一個內存 緩衝區(buffer)裏面,等到緩衝區被填滿,或者用戶執行 fsync 調用和 fdatasync 調用時,纔將儲存在緩衝區裏面的內容真正地寫入到硬盤裏面。

對於 AOF 持久化來說,當一條命令真正地被寫入到硬 盤裏面時,這條命令纔不會因爲停機而意外丟 失。

因此,AOF 持久化在遭遇停機時丟失命令的數量,取決於命令被寫入到硬 盤的時間:
• 越早將命令寫入到硬盤,發生意外停機時丟失的數據就越少;
• 而越遲將命令寫入到硬盤,發生意外停機時丟失的數據就越多。

安全性控制

爲了控制 Redis 服務器在遇到意外停機時丟失的數據量,Redis 爲 AOF 持久化提供了 appendfsync 選項,這個選項的值可以是 always 、 everysec 或者 no ,這些值的意思分別爲:
always :服務器每寫入一個命令,就 調用一次 fdatasync ,將緩衝區裏面的命令寫入到硬 盤裏面。在這種模式下,服務器即使遭遇意外停機,也不會 丟失任何已經成功執行的命令數據。

everysec :服務器每秒鐘調用一次 fdatasync ,將緩衝區裏面的命令寫入到硬 盤裏面。在這種模式下,服務器遭遇意外停機時,最多隻丟失一秒鐘內執行的命令數據。

no :服務器不主動調用 fdatasync ,由操作系統決定何時將緩衝區裏面的命令寫入到硬 盤裏面。在這種模式下,服務器遭遇意外停機時,丟失命令的數量是不確定的。

運行速度: always 的速度慢, everysec 和 no 都很快。
默認值: everysec 。

停機示例

在這裏插入圖片描述

AOF 重寫

創建一個沒有冗餘內容的新 AOF 文件

AOF 文件中的冗餘命令

隨着服務器的不斷運行,爲了記錄數據庫發生的變化,服務器會將越來越多的命令寫入到 AOF 文件裏面,使得 AOF 文件的體積不斷地增大。爲了讓 AOF 文件的大小控制在合理的範 圍,避免它胡亂地增長,Redis 提供了 AOF 重寫功能,通過 這個功能,服務器可以產生一個新的 AOF 文件:
• 新 AOF 文件記錄的數據庫數據和原有 AOF 文件記錄的數據庫數據完全一樣;
• 新的 AOF 文件會使用儘可能少的命令來 記錄數據庫數據,因此新 AOF 文件的體積通常會比原有 AOF 文件的體積要小得多。
• AOF 重寫期間,服務器不會被阻塞,可以正常 處理客戶端發送的命令請求。來看一個 AOF 重寫的示例。

AOF 重寫示例

在這裏插入圖片描述

AOF 重寫的觸發

有兩種方法可以觸發 AOF 重寫:

  1. 客戶端向服務器發送 BGREWRITEAOF 命令。
  2. 通過設置配置選項來讓服務器自動執行 BGREWRITEAOF 命令,它們分別是:
    • auto-aof-rewrite-min-size ,觸發 AOF 重寫所需的最小體積:只有在 AOF 文件的體積大於等於 size 時,服務器纔會考慮是否需要進行 AOF 重寫。這個選項用於避免對體積過小的 AOF 文件進行重寫。
    • auto-aof-rewrite-percentage ,指定觸發重寫所需的 AOF 文件體積百分比:當 AOF 文件的體積大於 auto-aof-rewrite-min-size 指定的體積,並且超過上一次重寫之後的 AOF 文件體積的 percent% 時,就會觸發 AOF 重寫。(如果服務器剛剛啓動不久,還沒有進行過 AOF 重寫,那麼使用服務器啓動時載入的 AOF 文件的體積來作爲基準值。)將這個值設置爲 0 表示關閉自動 AOF 重寫。

例子:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

複習

創建 RDB 文件需要將服務器包含的所有數據全部寫入到硬 盤裏面,這是一個非常耗費資源和時間的操作,因此服務器通常需要每隔一段時間才創建一個新的 RDB 文件,這使得服務器在遭遇意外停機時,可能會丟失大量數據。

AOF 持久化會將每個修改了數據 庫的命令都寫入到 AOF 文件末尾,在啓動服務器的時候,只要重新執行 AOF 文件包含的命令,就可以 還原服務器原有的數據庫數據。

因爲寫入緩衝區的存在,AOF 持久化的安全性取決於 緩衝區裏面的命令何時會被真正地寫入到硬盤裏面,通過設置 appendfsync 配置選項,用戶可以讓 AOF 持久化不丟失任何已經成功執行的命令數據,或者只丟失一秒鐘內被執行的命令數據,又或者不主 動執行 fdatasync 調用,將寫入硬盤的時機 交給操作系統來管理。

隨着服務器的運行,AOF 文件會產生越來越多冗餘命令,使得文件的體 積不斷增大,而通過執行 AOF 重寫操作,服務器可以創建一個保存相同數據庫數據,但不包含任何冗餘命令的新 AOF 文件,並使用這個新 AOF 文件來代替原有的 AOF 文件。

持久化對比

在這裏插入圖片描述
好消息:可以同時使用兩種持久化,根據你的需求來判斷。 還原數據優先使用 AOF 文件。

發佈了298 篇原創文章 · 獲贊 161 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章