一文詳細介紹Redis7持久化機制RDB和AOF
持久化方式
Redis提供了兩種數據持久化的方式,分別為RDB和AOF,RDB是基于內存快照的,它會將某一時刻Redis的內存狀態(tài)寫入磁盤,RDB也是Redis默認采用的持久化方式,AOF則是基于文件追加的機制來進行持久化的,如果我們開啟AOF持久化,那么每寫入一條數據,這個寫入數據的命令就會被追加到AOF文件的尾部,下面詳細介紹這兩種持久化方式。
RDB持久化
RDB是Redis默認的持久化方式,它是基于內存快照的持久化方式,何為快照?快照就是某一時刻Redis內存中的所有數據,就好比我們使用WPS編寫文檔,突然有事情需要處理,這時候我們要將電腦關閉,為了不讓編輯的內容丟失,我們關閉WPS時它會提醒保存文檔,這時候就會把到我們最后一刻操作之前的所有數據都保存下來,下次打開的時候 ,我們可以從上次編輯的地方繼續(xù)。
RDB配置
我們關注以下三個配置就行
save 3600 1 300 100 10 10000 dbfilename dump.rdb dir ./
save
配置達到什么條件才保存內存快照,這個配置表示如果在3600秒內進行一次寫操作,或者在300秒內進行100次寫操作,又在10秒內進行10000次寫操作,那么就會保存內存快照。
dbfilename
表示生成的RDB二進制文件名,默認為dump.db,dir ./是生成的RDB二進制文件的存放路勁。
當上面的save中的條件觸發(fā),那么Redis就會保存內存快照,當然,我們也可以直接使用SAVE和BGSAVE命令來保存內存快照,save這里的配置到最后還是去執(zhí)行SAVE和BGSAVE命令,下面介紹SAVE和BGSAVE命令。
SAVE和BGSAVE命令
在Redis命令行執(zhí)行SAVE命令或者BGSAVE命令都可能保存快照,只不過SAVE命令會阻塞Redis服務器,這時候客戶端發(fā)送的所有請求Redis都會拒絕,如果RDB文件比較小的還好,如果比較大,那么恢復數據就需要花費一定的時間,對于客戶端來就很不友好,所以這時候我們可以使用BGSAVE命令,執(zhí)行BGSAVE命令,Redis會fork一個子進程去保存內存快照,這樣Redis服務器就不會阻塞。
下面我們對配置進行修改來測試rdb。
改成下面配置,那么10s內如果有1次寫操作,就會保存當前快照。
save 3600 1 300 100 10 1
我們往Redis中添加一個key后,后臺就會打印保存到磁盤的日志。

在Redis源碼中,保存RDB文件在rdb.c文件中,使用rdbSaveBackgroup函數保存RDB文件,里面會fork一個子進程,然后調用rdbSave保存rdb文件。

恢復RDB文件
如果Redis服務發(fā)生宕機,那么在服務器恢復后,Redis會加載rdb文件進行恢復,Redis沒有專門恢復rdb文件的命令,服務器在啟動后會直接判斷是否存在rdb文件,如果存在則進行恢復。
在redis中,在rdb.c文件中使用rdbLoad函數進行加載rdb文件和恢復到Redis內存中。

AOF持久化
AOF (Append Only File)持久化機制會記錄每一條寫入 Redis 數據庫的命令,將其追加到文件末尾中,以此來保證數據的持久化和安全性。AOF 持久化方式保證了Redis的每一次寫的操作都可以被記錄到文件中,增加了數據的可靠性和穩(wěn)定性。這種方式下,每個寫入命令都將同步到 AOF 文件中。 AOF 優(yōu)先于 RBD 進行持久化,如果 Redis 服務重啟之前啟用了 AOF 持久化方式,那么 Redis 會自動從 AOF 日志文件中重建數據。 AOF 產生的日志文件是一個文本文件,易于查看,但也可能稍微耗時一些。
AOF配置
我們來關注AOF的幾個配置
appendonly yes appendfilename "appendonly.aof" appenddirname "appendonlydir" appendfsync everysec
appendonly
表示是否開啟AOF持久化機制,默認為no,表示不開啟,Redis默認不開啟AOF持久化,所以如果我們需要開啟AOF持久化,那么就需要將其設置為yes。
appendfilename
表示aof文件的名稱,開啟aof持久化,每個寫操作的命令會被寫入aof文件中,redis7以后,不單單生成了appendonly.aof文件,而是生成了三個文件,

appenddirname
表示aof所在文件夾的名稱,默認為appendonlydir。
appendfsync
表示設置同步aof文件的時機,當我們設置了aof持久化機制,寫入的命令并不會直接寫入磁盤中的aof文件,而是保存在內存的一個緩沖區(qū)aof_buf中,然后再通過相應的機制刷盤到磁盤中,提供了 always,everysec,no 三種選項
always:每當向緩沖區(qū)文件中添加數據時,立即執(zhí)行同步操作將緩沖區(qū)的內容同步到aof文件中。這樣可以保證數據的完整性,但會導致 Redis 性能下降。
everysec:每秒將aof緩沖區(qū)中的數據同步到磁盤。這種方式既保證了數據的完整性,又可以大大提高 Redis 的性能。
no:不執(zhí)行同步操作,而是交由操作系統(tǒng)控制同步時機。這種方案性能最好,但也有可能會導致數據丟失。
測試AOF持久化機制
開啟了AOF持久化機制后,我們往Redis中寫入幾條數據,然后查看aof文件。
往Redis中寫入了一個名為 steakliu 的key,value為空,然后為steakliu這個key設置value為 steakliu is a handsome boy,這是兩個命令,我們查看aof文件,發(fā)現里面有這兩條命令,里面還有一個 SELECT 0 ,它是Redis自動加入的。

在Redis中有一個時間循環(huán)機制,它會接受來自客戶端的請求,然后進行處理,當然也包括將命令寫入aof文件中,最終會調用flushAppendOnlyFile函數。

上面代碼中我們看到里面有一個aof_buf,它的類型是sds,在Redis中sds名為簡單動態(tài)字符串(Simple Dynamic String)。
sds aof_buf; /* AOF buffer, written before entering the event loop */
上面的配置中我們說了appendfsync,它的作用就是將aof_buf緩沖區(qū)中的數據同步到aof文件中。
通過AOF恢復數據
將Redis進程kill掉,然后重新啟動Redis,我們看出它會去加載aof文件進行數據恢復。

因為aof文件中保存的是寫操作的命令,所以在進行恢復的時候就是重新執(zhí)行一下這些命令就能進行恢復。
AOF重寫
隨著aof文件的變大,如果我們的Redis服務出現故障后重啟,它使用aof來恢復數據時,就會比較耗時,如果里面存在大量重復的命令,比如下面我們對steak-key進行反復的修改,但是實際上我們只需要最新的value,而里面出現了大量的重復,就會導致恢復時間比較慢。

為了解決這個問題,Redis提供了aof重寫機制,它使用了BGREWEITEAOF命令來對aof文件進行重寫,Redis會開啟一個子進程來進行重寫,它會編輯aof文件中命令,去除重復的,然后轉換到一個新的aof文件中。
循環(huán)添加重復的key
如下,我們往redis中循環(huán)添加兩個重復的key,分別是steak-key和steak-pai。

我們觀察一下aof文件夾中的幾個aof文件如下。

稍等一會兒,我們再看aof文件夾下面的這幾個aof文件如下:

從上面我們可以看出,appendonly.aof.1.base.aof變?yōu)榱?code>appendonly.aof.2.base.aof,appendonly.aof.1.incr.aof變?yōu)榱?code>appendonly.aof.2.incr.aof,由此可見aof文件發(fā)生了重寫。
我們查看appendonly.aof.2.base.aof的內容如下:

我們發(fā)現這個文件夾中只有兩個key,也就是steak-key和steak-pai,如果不進行重寫,那么就會存在大量重復的key,在進行恢復的時候就比較慢。
注:上面我們并沒有開啟RDB和AOF混合使用,所以我們能看到明文,如果開啟了RDB和AOF混合使用,文件中則有RDB二進制數據和AOF內容,我使用的是Redis7版本,默認是開啟RDB和AOF混合使用,可以在redis.conf中進行配置。
aof-use-rdb-preamble yes
yes表示開啟RDB和AOF混合使用,no表示關閉,Redis7默認的是開啟。
redis.conf配置
redis中有兩個aof重寫的配置。
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 表示當 AOF 文件大小增長到上一次重寫文件時的大小的百分之多少時,Redis 就會自動觸發(fā) AOF 重寫。例如,當此配置項為 100 時,表示當 AOF 文件大小增長到上次重寫時大小的兩倍時,就會自動觸發(fā) AOF 重寫。
auto-aof-rewrite-min-size 表示 Redis 在自動觸發(fā) AOF 重寫時設置的 AOF 文件最小大小限制。例如,當此配置項為 64MB 時,如果 AOF 文件大小增長到達了觸發(fā)自動重寫的條件,但當前 AOF 文件大小還不到 64MB,則不會自動觸發(fā) AOF 重寫。
從上面我們可以看出,aof如果不進行重寫,那么如果出現大量的重復key,aof文件中就會保存了大量重復的命令,在進行aof恢復的時候,會做很多無用功。
AOF和RDB優(yōu)缺點比較
RDB的優(yōu)點
RDB是一種快速而有效的備份方式,可以在特定的時間間隔內保存Redis數據的快照,儲存快照文件的方式是寫入硬盤中的二進制文件,所以很適合用來備份關鍵數據,RDB備份是二進制格式,所以比較小,使用起來比較節(jié)省存儲空間。RDB還支持壓縮備份,可以在備份數據時壓縮文件大小,節(jié)省備份成本。
RDB的缺點
RDB在執(zhí)行快照的時候,如果數據量較大,會造成Redis阻塞,如果服務器宕機,比如發(fā)生異常關機,那么這部分數據就可能發(fā)生丟失,因為RDB是定期進行備份,如果Redis服務器發(fā)生故障,那么會丟失上次備份到現在的數據。
AOF的優(yōu)點
AOF是一種以日志的形式來記錄Redis服務器所執(zhí)行的所有寫入操作,具有很好的復原能力,因此更適合于重要數據的保存,AOF支持在重寫,以保證AOF文件不會無限增大導致讀取緩慢。
AOF的缺點AOF文件通常比RDB文件大,如果日志分析不當,則可能增加服務器I/O的負載,AOF方式的數據恢復速度通常比RDB方式的恢復速度慢,因為它還需要去一個一個地執(zhí)行命令進行恢復。
AOF和RDB混合使用
AOF和RDB可以混合使用,上面我們也提到了RDB和AOF混合使用可通過aof-use-rdb-preamble配置,Redis7默認是開啟混合持久化的,那么就會將RDB二進制內容和AOF增量內容保存在一起。
關于Redis的持久化機制,我們就分享到這里!
以上就是一文詳細介紹Redis7持久化機制RDB和AOF的詳細內容,更多關于Redis7 RDB和AOF的資料請關注腳本之家其它相關文章!

