redis緩存架構詳解(三)-redis持久化-AOF持久化詳解

接上節,上節講解了RDB持久化,接下來我們講解AOF持久化,並比較兩者的優點與缺點。告訴您企業裏面怎麼做持久化。

2.3. AOF持久化

​ AOF機制對每條寫入命令以append-only的模式寫入一個日誌文件中,在redis重啓的時候,可以通過回放AOF日誌中的寫入指令來重新構建整個數據集。

2.3.1. AOF持久化原理

AOF持久化原理如下:

在這裏插入圖片描述

每當有一個寫命令過來時,就直接保存在我們的AOF文件中。

AOF 持久化功能的實現可以分爲命令追加( append )、文件寫入( write )、文件同步( sync )、文件重寫(rewrite)和重啓加載(load)。其流程如下:
  • 所有的寫命令會追加到 AOF 緩衝中。
  • AOF 緩衝區根據對應的策略向硬盤進行同步操作。
  • 隨着 AOF 文件越來越大,需要定期對 AOF 文件進行重寫,達到壓縮的目的。
  • 當 Redis 重啓時,可以加載 AOF 文件進行數據恢復。

2.3.2.文件重寫原理

AOF的方式也同時帶來了另一個問題。持久化文件會變的越來越大。爲了壓縮aof的持久化文件,redis提供了bgrewriteaof命令,將內存中的數據以命令的方式保存到臨時文件中,同時會fork出一條新進程來將文件重寫。

在這裏插入圖片描述

重寫aof文件的操作,並沒有讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似。

2.3.3.AOF也有三種觸發機制

(1)每修改就同步always:同步持久化 每次發生數據變更會被立即記錄到磁盤,性能較差,但數據完整性比較好。

(2)每秒同步everysec:異步操作,每秒記錄,如果一秒內宕機,有數據丟失。

(3)不同no:從不同步。

always、everysec、no之間的優缺點:

命令 優點 缺點
always 不丟失數據 IO開銷大,一般的sata盤只有幾百TPS
everysec 每秒一次fsync 丟1秒數據
no 不用管 不可控

2.3.4. AOF持久化機制的優點

(1)AOF可以更好的保護數據不丟失

AOF可以更好的保護數據不丟失,一般AOF會每隔1秒,通過一個後臺線程執行一次fsync操作,最多丟失1秒鐘的數據

(2)寫入性能非常高,文件不容易破損

AOF日誌文件以append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易破損,即使文件尾部破損,也很容易修復

(3)AOF日誌文件過大,也不會影響客戶端的讀寫

AOF日誌文件即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。因爲在rewrite log的時候,會對其中的指導進行壓縮,創建出一份需要恢復數據的最小日誌出來。再創建新日誌文件的時候,老的日誌文件還是照常寫入。當新的merge後的日誌文件ready的時候,再交換新老日誌文件即可。

(4)AOF日誌文件可讀性好,易做災難性恢復

AOF日誌文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有數據,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF文件,將最後一條flushall命令給刪了,然後再將該AOF文件放回去,就可以通過恢復機制,自動恢復所有數據


2.3.5. AOF持久化機制的缺點

(1)AOF日誌文件比RDB大

對於同一份數據來說,AOF日誌文件通常比RDB數據快照文件更大

(2)AOF文件同步頻率高,寫入性能相對低

AOF開啓後,支持的寫QPS會比RDB支持的寫QPS低,因爲AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的。

(3)AOF基於日誌做數據恢復,可能出現與原始數據不一樣的錯誤

以前AOF發生過bug,就是通過AOF記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的數據出來。所以說,類似AOF這種較爲複雜的基於命令日誌/merge/回放的方式,比基於RDB每次持久化一份完整的數據快照文件的方式,更加脆弱一些,容易有bug。不過AOF就是爲了避免rewrite過程導致的bug,因此每次rewrite並不是基於舊的指令日誌進行merge的,而是基於當時內存中的數據進行指令的重新構建,這樣健壯性會好很多。


2.3.6. AOF持久化配置與數據恢復實驗**

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上都沒有數據,那數據就永久丟失了。

2.4.RDB和AOF到底該如何選擇

Redis支持RDB和AOF兩種持久化,你可以兩者都用,可以選擇其中一種,根據場景來選擇。

(1)不要僅僅使用RDB,因爲那樣會導致你丟失很多數據。
(2)也不要僅僅使用AOF,因爲那樣有兩個問題,第一,你通過AOF做冷備,沒有RDB做冷備,來的恢復速度更快;
第二,RDB每次簡單粗暴生成數據快照,更加健壯,可以避免AOF這種複雜的備份和恢復機制的bug。
(3)綜合使用AOF和RDB兩種持久化機制,用AOF來保證數據不丟失,作爲數據恢復的第一選擇;
用RDB來做不同程度的冷備,在AOF文件都丟失或損壞不可用的時候,還可以使用RDB來進行快速的數據恢復。

2.5.RDB與AOF比較

RDB與AOF比較:

命令 啓動優先級 體積 恢復速度 數據安全性 輕重
RDB 丟數據
AOF 根據策略決定
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章