1. 程式人生 > >12.redis的AOF持久化深入講解各種操作和相關實驗

12.redis的AOF持久化深入講解各種操作和相關實驗

自動 percent fork 日誌 內存數據 文件中 aof 增長 機器

1、AOF持久化的配置

2、AOF持久化的數據恢復實驗
3、AOF rewrite
4、AOF破損文件的修復
5、AOF和RDB同時工作

------------------------------------------------------------------------------

1、AOF持久化的配置

AOF持久化,默認是關閉的,默認是打開RDB持久化

appendonly yes,可以打開AOF持久化機制,在生產環境裏面,一般來說AOF都是要打開的,除非你說隨便丟個幾分鐘的數據也無所謂

打開AOF持久化機制之後,redis每次接收到一條寫命令,就會寫入日誌文件中,當然是先寫入os cache的,然後每隔一定時間再fsync一下

而且即使AOF和RDB都開啟了,redis重啟的時候,也是優先通過AOF進行數據恢復的,因為aof數據比較完整

可以配置AOF的fsync策略,有三種策略可以選擇,一種是每次寫入一條數據就執行一次fsync; 一種是每隔一秒執行一次fsync; 一種是不主動執行fsync

always: 每次寫入一條數據,立即將這個數據對應的寫日誌fsync到磁盤上去,性能非常非常差,吞吐量很低; 確保說redis裏的數據一條都不丟,那就只能這樣了

mysql -> 內存策略,大量磁盤,QPS到多少,一兩k。QPS,每秒鐘的請求數量
redis -> 內存,磁盤持久化,QPS到多少,單機,一般來說,上萬QPS沒問題

everysec: 每秒將os cache中的數據fsync到磁盤,這個最常用的,生產環境一般都這麽配置,性能很高,QPS還是可以上萬的

no: 僅僅redis負責將數據寫入os cache就撒手不管了,然後後面os自己會時不時有自己的策略將數據刷入磁盤,不可控了

------------------------------------------------------------------------------

2、AOF持久化的數據恢復實驗

(1)先僅僅打開RDB,寫入一些數據,然後kill -9殺掉redis進程,接著重啟redis,發現數據沒了,因為RDB快照還沒生成
(2)打開AOF的開關,啟用AOF持久化
(3)寫入一些數據,觀察AOF文件中的日誌內容

其實你在appendonly.aof文件中,可以看到剛寫的日誌,它們其實就是先寫入os cache的,然後1秒後才fsync到磁盤中,只有fsync到磁盤中了,才是安全的,要不然光是在os cache中,機器只要重啟,就什麽都沒了

(4)kill -9殺掉redis進程,重新啟動redis進程,發現數據被恢復回來了,就是從AOF文件中恢復回來的

redis進程啟動的時候,直接就會從appendonly.aof中加載所有的日誌,把內存中的數據恢復回來

------------------------------------------------------------------------------

3、AOF rewrite

redis中的數據其實有限的,很多數據可能會自動過期,可能會被用戶刪除,可能會被redis用緩存清除的算法清理掉

redis中的數據會不斷淘汰掉舊的,就一部分常用的數據會被自動保留在redis內存中

所以可能很多之前的已經被清理掉的數據,對應的寫日誌還停留在AOF中,AOF日誌文件就一個,會不斷的膨脹,到很大很大

所以AOF會自動在後臺每隔一定時間做rewrite操作,比如日誌裏已經存放了針對100w數據的寫日誌了; redis內存只剩下10萬; 基於內存中當前的10萬數據構建一套最新的日誌,到AOF中; 覆蓋之前的老日誌; 確保AOF日誌文件不會過大,保持跟redis內存數據量一致

redis 2.4之前,還需要手動,開發一些腳本,crontab,通過BGREWRITEAOF命令去執行AOF rewrite,但是redis 2.4之後,會自動進行rewrite操作

在redis.conf中,可以配置rewrite策略

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

比如說上一次AOF rewrite之後,是128mb

然後就會接著128mb繼續寫AOF的日誌,如果發現增長的比例,超過了之前的100%,256mb,就可能會去觸發一次rewrite

但是此時還要去跟min-size,64mb去比較,256mb > 64mb,才會去觸發rewrite

(1)redis fork一個子進程
(2)子進程基於當前內存中的數據,構建日誌,開始往一個新的臨時的AOF文件中寫入日誌
(3)redis主進程,接收到client新的寫操作之後,在內存中寫入日誌,同時新的日誌也繼續寫入舊的AOF文件
(4)子進程寫完新的日誌文件之後,redis主進程將內存中的新日誌再次追加到新的AOF文件中
(5)用新的日誌文件替換掉舊的日誌文件

------------------------------------------------------------------------------

4、AOF破損文件的修復

如果redis在append數據到AOF文件時,機器宕機了,可能會導致AOF文件破損

用redis-check-aof --fix命令來修復破損的AOF文件

------------------------------------------------------------------------------

5、AOF和RDB同時工作

(1)如果RDB在執行snapshotting操作,那麽redis不會執行AOF rewrite; 如果redis再執行AOF rewrite,那麽就不會執行RDB snapshotting
(2)如果RDB在執行snapshotting,此時用戶執行BGREWRITEAOF命令,那麽等RDB快照生成之後,才會去執行AOF rewrite
(3)同時有RDB snapshot文件和AOF日誌文件,那麽redis重啟的時候,會優先使用AOF進行數據恢復,因為其中的日誌更完整

------------------------------------------------------------------------------

6、最後一個小實驗,讓大家對redis的數據恢復有更加深刻的體會

(1)在有rdb的dump和aof的appendonly的同時,rdb裏也有部分數據,aof裏也有部分數據,這個時候其實會發現,rdb的數據不會恢復到內存中
(2)我們模擬讓aof破損,然後fix,有一條數據會被fix刪除
(3)再次用fix得aof文件去重啟redis,發現數據只剩下一條了

數據恢復完全是依賴於底層的磁盤的持久化的,主要rdb和aof上都沒有數據,那就沒了

12.redis的AOF持久化深入講解各種操作和相關實驗