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

上一篇文章,咱們講的是 Redis 的一種基於內存快照的持久化存儲策略 RDB,本質上他就是讓 redis fork 出一個子進程遍歷咱們全部數據庫中的字典,進行磁盤文件的寫入。linux

但其實這種方式是有缺點的,先不說阻塞式 save 調用會阻塞整個 redis 服務,即使異步式 bgsave 也是基於時間間隔,每多少秒觸發了多少次更新操做纔會生成 RDB 文件,那麼若是某次 RDB 生成以後,緊接着服務宕機,就至少丟失幾秒甚至更多的數據,而且這些數據是沒法挽回的。redis

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

1、什麼是 AOF 持久化策略

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

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

image

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

你也能夠將 appendonly 選項指定爲 yes,而後執行一條 set 命令,看看 redis 根目錄下有沒有生成一個 appendonly.aof 文件。app

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

appendfsync 的配置項有如下三種值可選:函數

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

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

2、AOF 重寫

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

好比:

set a "a"
set b "b"
set c "c"
del a
del b
複製代碼

正常狀況下,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 重寫。

3、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 提供更高效率的數據持久化,期待中。

相關文章
相關標籤/搜索