AOF持久化(儲存的是操作redis命令)

oOo右右發表於2019-02-21

前言

AOF也就是:append only file,上一篇文章學習了rdb快照持久化儲存的是redis資料,aof持久化是儲存的是操作redis的命令。

 

AOF持久化的原理

理論上我們只需要儲存修改redis的命令(也就是寫命令)就能根據這些命令恢復我們的記憶體資料。AOF也就是使用這個原來備份和恢復redis。

如圖:

AOF配置

為了開啟 AOF 持久化的功能,我們只需要將 redis.conf 配置檔案中的appendonly配置選項設定為yes即可。涉及 AOF 持久化的幾個常用配置如下所示:

appendonly yes

appendfilename "appendonly.aof"

appendfsync everysec

  • appendonly:是否開啟 AOF 持久化功能
  • appendfilename:AOF 檔名稱
  • appendfsync:同步頻率,可選配置如表1所示

 

表 1:appendfsync 選項及同步頻率

選項 同步頻率

always 每個 Redis 命令都要同步寫入硬碟。這樣會嚴重降低 Redis 的效能

everysec 每秒執行一次同步,顯式地將多個寫命令同步到硬碟

no 讓作業系統來決定應該何時進行同步

aof持久化配置檔案例子:

appendonly yes

appendfilename "redis-63791.aof"

appendfsync always

port 63791

dir /diska/redis/

daemonize yes

logfile /data/logs/redis/redis_63791.log

pidfile /data/logs/redis/redis_63791.pid

 

# 配置當 AOF 檔案需要比舊 AOF 檔案增大多少時才進行 AOF 重寫

auto-aof-rewrite-percentage 50

# 配置當 AOF 檔案需要達到多大體積時才進行 AOF 重寫。只有這兩個配置的條件都達到時,才會進行 AOF 重寫

auto-aof-rewrite-min-size 10M

 

AOF 檔案生成過程

AOF 檔案的生成過程具體包括命令追加,檔案寫入,檔案同步三個步驟。

Redis 開啟 AOF 持久化功能後,Redis 在執行完一個寫命令後,都會將執行的寫命令追回到 Redis 內部的緩衝區的末尾。這個過程是命令的追加過程。

接下來,緩衝區的寫命令會被寫入到 AOF 檔案,這一過程是檔案寫入過程。對於作業系統來說,呼叫write函式並不會立刻將資料寫入到硬碟,為了將資料真正寫入硬碟,還需要呼叫fsync函式,呼叫fsync函式即是檔案同步的過程。只有經過檔案同步過程,AOF 檔案才在硬碟中真正儲存了 Redis 的寫命令。appendfsync 配置選項正是用來配置將寫命令同步到檔案的頻率的,各個選項的值的含義如表 1 所示。

AOF檔案

appendonly.aof以 Redis 協議格式 RESP 來儲存寫命令。由於 RESP 協議中包含了換行符,所以上面展示的 AOF 檔案時遇到換行符時進行了換行。在 AOF 檔案裡面,除了用於指定資料庫的 SELECT 命令是自動新增的之外,其他都是我們通過客戶端傳送的命令。

appendonly.aof儲存的命令會在 Redis 下次重啟時使用來還原 Redis 資料庫。

 

AOF檔案重寫和壓縮

aof持久化會把redis所有的寫命令都儲存到aof檔案,使得aof檔案越來越大,大大佔用磁碟使用空間,也給還原redis資料很大時間。

那麼怎麼解決?aof是記錄redis執行的寫命令也就是一些重複執行的寫命令都會記錄到aof檔案內,所以所刪除重複的寫入命令可以適當的縮小aof檔案大小。redis提供了bgrewriteaof命令可以實現:bgrewriteaof命令和bgsave命令原理差不多,執行後都會fork一個子程式進行重寫操作:

如:

執行一次 set a b後,檢視aof檔案大小:

-rw-r--r-- 1 root root 50 2月 21 23:11 redis-63791.aof

在執行多次set a b,在檢視aof檔案大小:

-rw-r--r-- 1 root root 586 2月 21 23:22 redis-63791.aof

可以看到aof檔案比原來大10倍

這時執行bgrewriteaof,檢視aof檔案大小:

-rw-r--r-- 1 root root 50 2月 21 23:24 redis-63791.aof

結論:執行bgrewriteaof後,重複的寫操作被刪除了!!

同時log如下:fork一個子程式操作的

注意:當aof檔案很大的時候執行bgrewriteaof會導致效能問題,為此redis也提供了對應策略:

auto-aof-rewrite-percentage 50 # 配置當 AOF 檔案需要比舊 AOF 檔案增大多少時才進行 AOF 重寫

auto-aof-rewrite-min-size 20M # 配置當 AOF 檔案需要達到多大體積時才進行 AOF 重寫。只有這兩個配置的條件都達到時,才會進行 AOF 重寫

這個是不是和rdb持久化中配置自動執行bgsave一個型別!!!

 

AOF 的優點

AOF 持久化的方法提供了多種的同步頻率,即使使用預設的同步頻率每秒同步一次,Redis 最多也就丟失 1 秒的資料而已。(保證資料完整性,對資料要求高的建議使用)

AOF 檔案使用 Redis 命令追加的形式來構造,因此,即使 Redis 只能向 AOF 檔案寫入命令的片斷,使用 redis-check-aof 工具也很容易修正 AOF 檔案。(容易修改寫入的命令)

AOF 檔案的格式可讀性較強,這也為使用者提供了更靈活的處理方式。例如,如果我們不小心錯用了 FLUSHALL 命令,在重寫還沒進行時,我們可以手工將最後的 FLUSHALL 命令去掉,然後再使用 AOF 來恢復資料。

 

AOF 的缺點

對於具有相同資料的的 Redis,AOF 檔案通常會比 RDF 檔案體積更大。

雖然 AOF 提供了多種同步的頻率,預設情況下,每秒同步一次的頻率也具有較高的效能。但在 Redis 的負載較高時,RDB 比 AOF 具好更好的效能保證。

RDB 使用快照的形式來持久化整個 Redis 資料,而 AOF 只是將每次執行的命令追加到 AOF 檔案中,因此從理論上說,RDB 比 AOF 方式更健壯。官方文件也指出,AOF 的確也存在一些 BUG,這些 BUG 在 RDB 沒有存在

 

備註:

  1. https://redis.io/topics/persistence
  2. https://redis.io/topics/protocol

 

 

 

 

 

相關文章