1. 程式人生 > >redis學習系列(四)--redis的AOF持久化深入理解各種操作和相關實驗

redis學習系列(四)--redis的AOF持久化深入理解各種操作和相關實驗

目錄


1、AOF持久化的配置


AOF持久化預設是關閉的,預設是開啟RDB持久化
appendonly yes,(在redis.conf中修改appendonly 的策略,將no改成yes即可)此配置可以開啟AOF持久化機制,在生產環境裡面,一般來說AOF都是要開啟的,除非你說隨便丟個幾分鐘的資料也無所謂
開啟AOF持久化機制之後,redis每次接收到一條寫命令,就會寫入日誌檔案中,當然是先寫入os cache的,然後每隔一定時間再fsync一下
而且即使AOF和RDB都開啟了,redis重啟的時候,也是優先通過AOF進行資料恢復的,因為aof資料比較完整
可以配置AOF的fsync策略,有三種策略可以選擇,一種是每次寫入一條資料就執行一次fsync; 一種是每隔一秒執行一次fsync; 一種是不主動執行fsync
appendfsync always: 每次寫入一條資料,立即將這個資料對應的寫日誌fsync到磁碟上去,效能非常非常差,吞吐量很低; 確保說redis裡的資料一條都不丟,那就只能這樣了
appendfsync everysec: 每秒將os cache中的資料fsync到磁碟,這個最常用的,生產環境一般都這麼配置,效能很高,QPS還是可以上萬的(QPS指每秒鐘請求次數)
appendfsync 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之前,還需要手動開發一些指令碼去進行rewrite操作(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
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裡也有部分資料,aof裡也有部分資料,這個時候其實會發現,rdb的資料不會恢復到記憶體中

發現我們為rdb設定了一個save 5 1的檢查點,即每五秒有一個快取資料新增,就執行rdb檔案的write,我們現在將之關閉,然後再新增兩對資料,這時候效果應該是aof檔案裡面儲存的快取資料比rdb的多兩對,將redis服務kill掉,然後重啟之後發現,之前儲存的兩對資料都可以get