Redis 中的數據持久化策略(AOF)

AOF 是 redis 中的另一種數據持久化策略,它基於操作日誌,也是一個很優秀的持久化策略,當然也有缺點。那麼本篇就來講講這個 AOF 持久化策略。

一、什麼是 AOF 持久化策略

AOF 即 append only file,當 redis 採用這這種數據持久化策略的時候,每當 redis 服務器收到一條更新命令時,操作結束之後會將這條命令添加到 aof 內存緩衝區,特定的時間下刷新緩衝區到磁盤文件中,也就是我們的 aof 文件。

默認的 redis 啟動配置文件中,會有這麼兩條配置:

Redis 中的數據持久化策略(AOF)

appendonly指定 redis 是否啟用 AOF 持久化策略, appendfilename 指明生成的 AOF 文件名稱。

你也可以將 appendonly 選項指定為 yes,然後執行一條 set 命令,看看 redis 根目錄下有沒有生成一個 appendonly.aof 文件。

redis.conf 中還有 appendfsync 這麼一條配置,它指明 AOF 文件的寫入頻率,即便 linux 中文件 IO 使用的高效的 epoll,但每收到一條更新命令就進行一次文件 IO,未免也太低效,況且也沒必要。

appendfsync 的配置項有以下三種值可選:

  • always:每一次系統 serverCorn 函數調用就刷新一次緩存區
  • everysec:每秒執行一次磁盤寫入,期間所有的命令都會存儲在 aof 緩存區
  • no:不做控制,任由操作系統決定什麼時候刷新緩衝區

redis 默認配置是 everysec,即每秒刷新一次緩存區。

二、AOF 重寫

所以,理論上來說,隨著 redis 服務器運行時間的持續,生成的 aof 文件只會越來越大,redis 提供 AOF 重寫策略幫助優化和壓縮 aof 文件。

比如:

<code>set a "a"set b "b"set c "c"del adel b/<code>

正常情況下,aof 文件中會保存著五條命令的 log,然後數據恢復的時候依次執行即可。而當你啟動 AOF 重寫後,實際上我們的 aof 文件中只有 set c "c" 這一條命令的 log。

以上只是一個簡單的示例,實際上 AOF 重寫達到的效率比這優秀的多的多,往往能將幾百條甚至幾千條的命令日誌,重寫優化成個位數。帶給我們最直觀的好處就是,aof 文件體積變小,數據恢復速度變快。

一般來說,我們可以通過向 redis 服務器發送 bgrewriteaof 命令觸發服務器對 aof 文件進行重寫,如果當前有正在運行的重寫子進程,則本次重寫 會推遲執行,否則,直接觸發一次重寫。

除此之外,我們還可以在配置文件中配置 aof 文件達到多大,自動觸發文件重寫。

因為 aof 文件重寫一樣是 fork 子進程並由子進程處理的,主進程依然提供服務,所以 redis 還提供一塊重寫緩衝區,當發現有子進程正在進行 aof 文件重寫,最新的請求命令除了會添加到 AOF 緩衝區,還會添加進 AOF 重寫緩衝區,當子進程完成重寫任務後,主進程

阻塞式 將重寫緩衝區的命令日誌添加進最新的 aof 文件中。

看幾條配置

no-appendfsync-on-rewrite配置了當 redis 服務器因為某些情況即將阻塞(例如 save)時是否需要將緩衝區中的 aof 命令寫入到磁盤,配置 yes 則每次遇到阻塞操作時刷新緩存到磁盤,配置為 no 則無需關心服務器阻不阻塞,緩存命令在緩存區。

auto-aof-rewrite-percentage配置了當 aof 文件相較於上一版本的 aof 文件大小的百分比達到多少時觸發 AOF 重寫。舉個例子,auto-aof-rewrite-percentage 選項配置為 100,上一版本的 aof 文件大小為 100M,那麼當我們的 aof 文件達到 200M 的時候,觸發 AOF 重寫。

auto-aof-rewite-min-size配置了最小能容忍 aof 文件大小,超過這個大小必須進行 AOF 重寫。

三、RDB 與 AOF

RDB 基於內存快照,有兩種方式 save 和 bgsave,前者會阻塞 redis 服務,後者是異步 fork 子進程不影響主進程提供服務。大部分情況,我們會通過配置時間間隔觸發 RDB 文件寫入。RDB 文件中保存的是 redis 內存中所有的數據一份快照。

優點是:

  1. 相同的數據量下,rdb 文件要小於 aof 文件,且恢復速度要快於 aof
  2. rdb 文件中是整個數據的完整備份快照,數據存儲緊湊即便不同版本的 redis,也能順利恢復
  3. 整個 rdb 持久化,只需要 fork 一個子進程進行持久化即可,父進程依然可以提供服務,效率最大化

缺點是:

  1. 容易丟失數據,即便配置了事件時間觸發備份,也至少丟失一秒數據
  2. 如果數據量太大,fork 子進程的時候會阻塞毫秒級別時間

AOF 是基於命令操作日誌,每條更新命令都會被刷到緩存區,然後在特定的時間節點被寫入 aof 磁盤文件。

優點是:

  1. 相較於 RDB,AOF 數據可靠性更強,最多丟失一秒數據
  2. 數據庫容錯率變好,一些誤操作可以通過直接改 aof 文件進行回退

缺點是:

  1. AOF 文件通常較大且恢復效率比不上 RDB,不適合做數據冷備份

總的來說,AOF 策略會使數據穩定性更高,具有更完整的數據備份,RDB 恢復效率高適合做災難恢復,建議生產環境上兩者都開啟。

ps:Redis 官方號稱後續出一個新的持久化策略,整合 RDB 和 AOF 提供更高效率的數據持久化,期待中。


分享到:


相關文章: