原文:
redis 系列17 持久化 aof
一.概述
1.1 aof持久化的實現
(1) 命令追加
當aof執行處於開啟狀態時,伺服器在執行完乙個寫命令之後,會以協議格式將被執行的寫命令追加到伺服器狀態的aof_buf緩衝區的末尾。
structredisserver
(2) aof檔案寫入與同步
127.0.0.1:6379>config get1) "
"2) "
everysec
"
模式
對應函式行為no
但同步到磁碟不及時,是最不安全的選擇。
everysec (推薦)
always
1.2 aof檔案載入與資料還原
因為aof檔案裡面包含了重建資料庫狀態所需的所有寫命令,所以伺服器只要讀入並重新執行一遍aof檔案裡面儲存的寫命令,就可以還原伺服器關閉之前的資料庫狀態。redis讀取aof檔案並還原資料庫狀態的詳細步驟如下:
(1) 建立乙個偽客戶端(因為redis的命令只能在客戶端上下文中執行),用於載入aof檔案時所使用的命令直接**於aof檔案,而不是來自網路連線的命令。
(2) 從aof檔案中分析並讀出一條寫命令。
(3) 使用偽客戶端執行被讀出的寫命令。
(4) 重複執行步驟2和3,直到aof檔案中的所有命令都被處理完為止。
1.3 aof重寫
因為aof持久化是通過儲存被執行的寫命令來記錄資料庫狀態的,所以隨著伺服器執行時間的流逝,aof檔案中的內容會越來越多,檔案 的體積也會越來越大,隨著aof檔案的體積越大,資料還原所需的時間就越多。為了解決aof檔案體積膨脹的問題,redis提供了aof檔案重寫功能。通過該功能,redis伺服器可以建立乙個新的aof檔案來替代現有的aof檔案,新舊兩個aof檔案所儲存的資料庫狀態相同,但新的aof檔案不會包含任何浪費空間的冗餘命令,所以新aof檔案體積比舊的aof檔案體積要小得多。
aof檔案重寫並不需要對現有的aof檔案進行任何讀取,分析或者寫入操作,這個重寫功能是通過讀取伺服器當前的資料庫狀態來實現的。比如:使用寫命令 rpush list "a", rpush list "b", rpush list "c", rpush list "d" 此時必須在aof檔案中寫入四條命令。重寫可以是直接從資料庫中讀取鍵list的值,然後用一條rpush list "a","b","c","d"命令來代替。
1.4 aof 後台重寫
重寫作為一種輔助維護,redis不希望aof重寫造成伺服器無法處理請求,所以redis決定將aof重寫程式放到子程序裡執行。對aof 檔案進行重寫,執行bgrewriteaof命令, redis將生成乙個新的 aof 檔案,這個檔案包含重寫當前資料集所需的最少命令。bgrewriteaof後台重寫實現步驟如下:
(1) redis執行 fork() ,現在同時擁有父程序和子程序。
(2)子程序開始將新 aof 檔案的內容寫入到臨時檔案。
(3)對於所有新執行的寫入命令,父程序一邊將它們累積到乙個記憶體快取中,一邊將這些改動追加到現有 aof 檔案的末尾,這樣樣即使在重寫的中途發生停機,現有的 aof 檔案也還是安全的。
(4)當子程序完成重寫工作時,它給父程序傳送乙個訊號,父程序在接收到訊號之後,將記憶體快取中的所有資料追加到新 aof 檔案的末尾。
(5)現在redis原子地用新檔案替換舊檔案,之後所有命令都會直接追加到新 aof 檔案的末尾。
1.5 aof優點
(1) 可以使用不同的fsync(同步)策略:無fsync、每秒fsync、每次寫的時候fsync。使用預設的每秒fsync策略,redis的效能依然很好(fsync是由後台執行緒進行處理的,主線程會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的資料。
(2) aof檔案是乙個只進行追加的日誌檔案,所以不需要寫入seek,某些原因(如:宕機)未執行完整的寫入命令,你也可使用redis-check-aof工具修復這些問題。
(3) aof 檔案體積變得過大時,自動地在後台對 aof 進行重寫.整個重寫操作是絕對安全,即使重寫過程中發生停機,現有的 aof 檔案也不會丟失。一旦新 aof 檔案建立完畢,redis就會從舊 aof 檔案切換到新 aof 檔案,並開始對新 aof 檔案進行追加操作。
(4) aof 檔案有序地儲存了對資料庫執行的所有寫入操作,這些寫入操作以redis協議的格式儲存,因此 aof 檔案的內容非常容易被人讀懂,對檔案進行分析(parse)也很輕鬆。匯出(export) aof 檔案也非常簡單。舉個例子:如果你不小心執行了 flushall 命令,但只要 aof 檔案未被重寫,那麼只要停止伺服器,移除 aof 檔案末尾的 flushall 命令,並重啟redis,就可以將資料集恢復到 flushall 執行之前的狀態。
1.5 aof缺點
(1) 對於相同的資料集來說,aof 檔案的體積通常要大於 rdb 檔案的體積。
(2) 根據所使用的fsync(同步)策略,aof 的速度可能會慢於 rdb 。在一般情況下,每秒fsync的效能依然非常高,而關閉fsync可以讓 aof 的速度和 rdb 一樣快,即使在高負荷之下也是如此。不過在處理巨大的寫入載入時,rdb 可以提供更***的最大延遲時間(latency)。
1.6 如何選擇使用哪種持久化方式
一般來說,如果想達到足以媲美postgresql的資料安全性,應該同時使用兩種持久化功能。如果你非常關心你的資料,但仍然可以承受數分鐘以內的資料丟失,那麼你可以只使用 rdb 持久化。
有很多使用者都只使用 aof 持久化,但我們並不推薦這種方式:因為定時生成 rdb 快照(snapshot)非常便於進行資料庫備份,並且 rdb 恢復資料集的速度也要比 aof 恢復的速度要快,除此之外,使用 rdb 還可以避免之前提到的 aof 程式的 bug 。注意: 因為以上提到的種種原因,未來可能會將 aof 和 rdb 整合成單個持久化模型。
二. aof持久化配置
redis預設是關閉aof機制,需要在配置檔案中開啟aof, 注意通過 config set 設定的配置重啟redis服務後就會失效,如果要永久有效,需在redis.conf中開啟aof功能。指令碼如下:
127.0.0.1:6379>config setok
開啟後每當redis執行乙個改變資料集的命令時(如:set),這個命令就會被追加到aof檔案的末尾,這樣當redis重新啟動時,程式就可以通過重新執行aof檔案中的命令來達到重建資料集的目的。
2.1 aof配置相關選項
選項
取值
說明
no|yes
是否開啟aof機制
aof檔名
aof持久化同步頻率
no | yes
在日誌進行bgrewriteaof時,如果設定為yes表示新寫操作不進行同步fsync,只是暫存在緩衝區裡,避免造成磁碟io操作衝突,等重寫完成後在寫入。redis中預設為no
auto-aof-rewrite-percentage
當前aof檔案大小是上次日誌重寫時的aof檔案大小兩倍時,發生bgrewriteaof操作。
auto-aof-rewrite-min-size
64mb
當前aof檔案執行bgrewriteaof命令的最小值,避免剛開始啟動reids時由於檔案尺寸較小導致頻繁的bgrewriteaof。
aof-load-truncated
yesredis再恢復時,忽略最後一條可能存在問題的指令
aof-use-rdb-preamble
no新增rdb-aof混合持久化格式,在開啟了這個功能之後,aof重寫產生的檔案將同時包含rdb格式的內容和aof格式的內容
2.2 演示
下面測試aof持久化,aof檔案是可識別的純文字,檔案的內容就是乙個個的redis標準命令,下面使用兩個set命令:
127.0.0.1:6379> set name1 "zs"ok
127.0.0.1:6379> set name2 "ls"
ok
下面檢視aof檔案, 可以發現裡面是乙個個命令, 上面執行的寫命令對應的檔案內容如下:
name1
$2zs
*3$3
set$
5name2
$2ls
redis持久化 AOF持久化
1.aof持久化原理 aof持久化會將被執行的寫命令寫到aof檔案的末尾。在恢復的時候,redis只要從頭到尾重新執行一次aof檔案包含的所有寫命令 2.配置選項 固態硬碟禁用always選項,在某些情況頻繁讀寫會大大降低固態硬碟的壽命 4.aof檔案的重寫和壓縮 aof檔案裡面記錄了所有的命令而不...
redis持久化之AOF持久化
aof與rdb持久化通過儲存資料庫中的鍵值對來記錄資料庫狀態不同,aof持久化是通過儲存redis伺服器所執行的寫命令來記錄資料庫狀態的。被寫入aof檔案的所有命令都是以redis的命令請求協議格式儲存的。當aof持久化功能處於開啟狀態,伺服器在執行完乙個寫命令之後,會以協議格式將被執行的寫命令追加...
Redis的持久化 AOF
redis的aof持久化策略是將傳送到redis服務端的每一條命令都記錄下來,並且儲存到硬碟中的aof檔案中,類似打日誌檔案,來一條命令就記錄一條。aof設定 aof測試 當客戶端向伺服器傳送一些redis命令時,redis會將所執行的命令記錄到aof檔案中,如下所示 當redis伺服器重啟後,會將...