redis 系列17 持久化 AOF

2021-09-08 23:01:26 字數 4440 閱讀 9319

原文:

redis 系列17 持久化 aof

一.概述

1.1 aof持久化的實現

(1) 命令追加

當aof執行處於開啟狀態時,伺服器在執行完乙個寫命令之後,會以協議格式將被執行的寫命令追加到伺服器狀態的aof_buf緩衝區的末尾。

struct

redisserver

(2) aof檔案寫入與同步

127.0.0.1:6379>config get

1) "

"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 set

ok

開啟後每當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伺服器重啟後,會將...