Redis的持久化詳解
一、Redis的持久化
Redis是一個(gè)基于內(nèi)存的數(shù)據(jù)庫(kù),它的數(shù)據(jù)是存放在內(nèi)存中,內(nèi)存有個(gè)問(wèn)題就是關(guān)閉服務(wù)或者斷電會(huì)丟失。Redis的數(shù)據(jù)也支持寫(xiě)到硬盤(pán)中,這個(gè)過(guò)程就叫做持久化。
Redis提供了2種不同形式的持久化方式:
- RDB(Redis DataBase) :簡(jiǎn)而言之,就是在指定的時(shí)間間隔內(nèi),定時(shí)的將 redis 存儲(chǔ)的數(shù)據(jù)生成Snapshot快照并存儲(chǔ)到磁盤(pán)等介質(zhì)上;
- AOF(Append Of File) :將 redis 執(zhí)行過(guò)的所有寫(xiě)指令記錄下來(lái),在下次 redis 重新啟動(dòng)時(shí),只要把這些寫(xiě)指令從前到后再重復(fù)執(zhí)行一遍,就可以實(shí)現(xiàn)數(shù)據(jù)恢復(fù)了。
RDB(Redis DataBase):redis備份默認(rèn)方式
同時(shí)允許使用兩種方式: 其實(shí) RDB 和 AOF 兩種方式也可以同時(shí)使用,在這種情況下,如果 redis 重啟的話,則會(huì)優(yōu)先采用 AOF 方式來(lái)進(jìn)行數(shù)據(jù)恢復(fù),這是因?yàn)?AOF 方式的數(shù)據(jù)恢復(fù)完整度更高。
可以選擇關(guān)閉持久化: 如果你沒(méi)有數(shù)據(jù)持久化的需求,也完全可以關(guān)閉 RDB 和 AOF 方式,這樣的話,redis 將變成一個(gè)純內(nèi)存數(shù)據(jù)庫(kù),就像 memcache 一樣。
官網(wǎng)介紹:
https://redis.com.cn/redis-persistence.html
https://redis.com.cn/topics/persistence.html#redis
二、RDB(Redis DataBase)
1、RDB快照原理
我們知道 Redis 是單線程程序,這個(gè)線程要同時(shí)負(fù)責(zé)多個(gè)客戶端套接字的并發(fā)讀寫(xiě)操作和內(nèi)存數(shù)據(jù)結(jié)構(gòu)的邏輯讀寫(xiě)
。
在服務(wù)線上請(qǐng)求的同時(shí),Redis 還需要進(jìn)行內(nèi)存快照,內(nèi)存快照要求 Redis 必須進(jìn)行文件 IO 操作,這意味著單線程同時(shí)在服務(wù)線上的請(qǐng)求還要進(jìn)行文件 IO 操作
,文件 IO 操作會(huì)嚴(yán)重拖垮服務(wù)器請(qǐng)求的性能。還有個(gè)重要的問(wèn)題是為了不阻塞線上的業(yè)務(wù),就需要邊持久化邊響應(yīng)客戶端請(qǐng)求
。持久化的同時(shí),內(nèi)存數(shù)據(jù)結(jié)構(gòu)還在改變,比如一個(gè)大型的 hash 字典正在持久化,結(jié)果一個(gè)請(qǐng)求過(guò)來(lái)把它給刪掉了,還沒(méi)持久化完呢,這要怎么搞?
Redis 使用操作系統(tǒng)的多進(jìn)程 COW(Copy On Write)
機(jī)制來(lái)實(shí)現(xiàn)快照持久化,這個(gè)機(jī)制很有意思,也很少人知道。多進(jìn)程 COW 也是鑒定程序員知識(shí)廣度的一個(gè)重要指標(biāo)。
fork(多進(jìn)程)
Redis 在持久化時(shí)會(huì)調(diào)用 glibc 的函數(shù) fork 產(chǎn)生一個(gè)子進(jìn)程,快照持久化完全交給子進(jìn)程來(lái)處理,父進(jìn)程繼續(xù)處理客戶端請(qǐng)求。子進(jìn)程剛剛產(chǎn)生時(shí),它和父進(jìn)程共享內(nèi)存里面的代碼段和數(shù)據(jù)段。
這時(shí)你可以將父子進(jìn)程想像成一個(gè)連體嬰兒,共享身體。這是 Linux 操作系統(tǒng)的機(jī)制,為了節(jié)約內(nèi)存資源,所以盡可能讓它們共享起來(lái)。在進(jìn)程分離的一瞬間,內(nèi)存的增長(zhǎng)幾乎沒(méi)有明顯變化。
子進(jìn)程做數(shù)據(jù)持久化,它不會(huì)修改現(xiàn)有的內(nèi)存數(shù)據(jù)結(jié)構(gòu),它只是對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行遍歷讀取,然后序列化寫(xiě)到磁盤(pán)中。但是父進(jìn)程不一樣,它必須持續(xù)服務(wù)客戶端請(qǐng)求,然后對(duì)內(nèi)存數(shù)據(jù)結(jié)構(gòu)進(jìn)行不間斷的修改。
這個(gè)時(shí)候就會(huì)使用操作系統(tǒng)的 COW 機(jī)制來(lái)進(jìn)行數(shù)據(jù)段頁(yè)面的分離。數(shù)據(jù)段是由很多操作系統(tǒng)的頁(yè)面組合而成,當(dāng)父進(jìn)程對(duì)其中一個(gè)頁(yè)面的數(shù)據(jù)進(jìn)行修改時(shí),會(huì)將被共享的頁(yè)面復(fù)制一份分離出來(lái),然后對(duì)這個(gè)復(fù)制的頁(yè)面進(jìn)行修改。這時(shí)子進(jìn)程相應(yīng)的頁(yè)面是沒(méi)有變化的,還是進(jìn)程產(chǎn)生時(shí)那一瞬間的數(shù)據(jù)。
隨著父進(jìn)程修改操作的持續(xù)進(jìn)行,越來(lái)越多的共享頁(yè)面被分離出來(lái),內(nèi)存就會(huì)持續(xù)增長(zhǎng)。但是也不會(huì)超過(guò)原有數(shù)據(jù)內(nèi)存的 2 倍大小
。另外一個(gè) Redis 實(shí)例里冷數(shù)據(jù)占的比例往往是比較高的,所以很少會(huì)出現(xiàn)所有的頁(yè)面都會(huì)被分離
,被分離的往往只有其中一部分頁(yè)面。每個(gè)頁(yè)面的大小只有 4K,一個(gè) Redis 實(shí)例里面一般都會(huì)有成千上萬(wàn)的頁(yè)面。
子進(jìn)程因?yàn)閿?shù)據(jù)沒(méi)有變化,它能看到的內(nèi)存里的數(shù)據(jù)在進(jìn)程產(chǎn)生的一瞬間就凝固了,再也不會(huì)改變,這也是為什么 Redis 的持久化叫「快照」的原因。接下來(lái)子進(jìn)程就可以非常安心的遍歷數(shù)據(jù)了進(jìn)行序列化寫(xiě)磁盤(pán)了。
這里之需要需要通知父線程,是因?yàn)楦妇€程要做個(gè)記錄,保留最后一次持久化的時(shí)間。
2、RDB配置
(1)指定備份文件的名稱
在redis.conf中,可以修改rdb備份文件的名稱,默認(rèn)為dump.rdb,如下:
(2)指定備份文件存放的目錄
在redis.conf中,rdb文件的保存的目錄是可以修改的,默認(rèn)為Redis啟動(dòng)命令所在的目錄,如下
(3)觸發(fā)RDB備份
方式1:自動(dòng)備份,需配置備份規(guī)則
可在redis.conf中配置自動(dòng)備份的規(guī)則,默認(rèn)規(guī)則如下:
save用來(lái)配置備份的規(guī)則
save的格式: save 秒鐘 寫(xiě)操作次數(shù)
默認(rèn)是1分鐘內(nèi)修改了1萬(wàn)次,或5分鐘內(nèi)需修改了10次,或30分鐘內(nèi)修改了1次。
示例:設(shè)置20秒內(nèi)有最少有3次key發(fā)生變化,則進(jìn)行備份
save 20 3
方式2:手動(dòng)執(zhí)行命令備份(save | bgsave)
有2個(gè)命令可以觸發(fā)備份。
save
:save時(shí)只管保存,其他不管,全部阻塞,手動(dòng)保存,不建議使用。bgsave
:redis會(huì)在后臺(tái)異步進(jìn)行快照操作,快照同時(shí)還可以響應(yīng)客戶端情況。
可以通過(guò) lastsave
命令獲取最后一次成功生成快照的時(shí)間(獲取到的是時(shí)間戳)。
方式3:flushall命令
執(zhí)行flushall命令,也會(huì)產(chǎn)生dump.rdb文件,但里面是空的,無(wú)意義。
(4)動(dòng)態(tài)停止RDB: redis-cli config set save ""
#save后給空值,表示禁用保存策略。
3、redis.conf 其他一些配置
(1)stop-writes-on-bgsave-error:當(dāng)磁盤(pán)滿時(shí),是否關(guān)閉redis的寫(xiě)操作
stop-writes-on-bgsave-error用來(lái)指定當(dāng)redis無(wú)法寫(xiě)入磁盤(pán)的話,是否直接關(guān)掉redis的寫(xiě)操作,
推薦yes。
(2)rdbcompression:rdb備份是否開(kāi)啟壓縮
對(duì)于存儲(chǔ)到磁盤(pán)中的rdb快照文件,可以設(shè)置是否進(jìn)行壓縮,如果是的話,redis會(huì)采用LZF算法進(jìn)行壓縮。如果你不想消耗CPU來(lái)進(jìn)行壓縮的話,可以設(shè)置為關(guān)閉此功能,推薦yes。
(3)rdbchecksum:是否檢查rdb備份文件的完整性
存儲(chǔ)快照后,還可以讓redis使用CRC64算法來(lái)進(jìn)行數(shù)據(jù)校驗(yàn),但是這樣做會(huì)增加大約10%的性能消耗,如果希望獲取最大的性能提升,可以關(guān)閉此功能。
推薦yes。
4、RDB的備份恢復(fù)
(1)先通過(guò)CONFIG GET dir
查詢r(jià)db文件的目錄,這其實(shí)就是查的redis.conf
文件當(dāng)中通過(guò)dir
設(shè)置的目錄
(2)停止Redis
(3)拷貝遷移的redis備份文件(dump.rdb)到CONFIG GET dir
查詢出來(lái)的指定目錄下。
cp dump.rdb dump.rdb
(4)重新啟動(dòng)redis服務(wù)
5、RDB優(yōu)缺點(diǎn)
優(yōu)勢(shì):
- 適合大規(guī)模數(shù)據(jù)恢復(fù)
- 對(duì)數(shù)據(jù)完整性和一致性要求不高更適合使用
- 節(jié)省磁盤(pán)空間
- 基于二進(jìn)制存儲(chǔ)的,恢復(fù)速度快
劣勢(shì):
- Fork的時(shí)候,內(nèi)存中的數(shù)據(jù)會(huì)被克隆一份,大致2倍的膨脹,需要考慮
- 雖然Redis在fork的時(shí)候使用了寫(xiě)時(shí)拷貝技術(shù),但是如果數(shù)據(jù)龐大時(shí)還是比較消耗性能
- 在備份周期在一定間隔時(shí)間做一次備份,所以如果Redis意外down的話,就會(huì)丟失最后一次快照后所有修改
三、AOF(Append Of File)
1、AOF原理
AOF 日志存儲(chǔ)的是 Redis 服務(wù)器的順序指令序列,AOF 日志只記錄對(duì)內(nèi)存進(jìn)行修改的指令記錄。
假設(shè) AOF 日志記錄了自 Redis 實(shí)例創(chuàng)建以來(lái)所有的修改性指令序列,那么就可以通過(guò)對(duì)一個(gè)空的 Redis 實(shí)例順序執(zhí)行所有的指令,也就是「重放」,來(lái)恢復(fù) Redis 當(dāng)前實(shí)例的內(nèi)存數(shù)據(jù)結(jié)構(gòu)的狀態(tài)。
(1)寫(xiě)入機(jī)制
Redis 在收到客戶端修改命令后,先進(jìn)行相應(yīng)的校驗(yàn),如果沒(méi)問(wèn)題,就立即將該命令存追加到 .aof 文件中,也就是先存到磁盤(pán)中,然后服務(wù)器再執(zhí)行命令。這樣就算遇到了突發(fā)的宕機(jī)情況情況,也只需將存儲(chǔ)到 .aof 文件中的命令,進(jìn)行一次“命令重演”就可以恢復(fù)到宕機(jī)前的狀態(tài)。
(2)寫(xiě)入緩存
在上述執(zhí)行過(guò)程中,有一個(gè)很重要的環(huán)節(jié)就是命令的寫(xiě)入,這是一個(gè) IO 操作。Redis 為了提升寫(xiě)入效率,它不會(huì)將內(nèi)容直接寫(xiě)入到磁盤(pán)中,而是將其放到一個(gè)內(nèi)存緩存區(qū)(buffer)中
,等到緩存區(qū)被填滿時(shí)采用異步真正將緩存區(qū)中的內(nèi)容寫(xiě)入到磁盤(pán)里。
這就意味著如果機(jī)器突然宕機(jī),AOF 日志內(nèi)容可能還沒(méi)有來(lái)得及完全刷到磁盤(pán)中,這個(gè)時(shí)候就會(huì)出現(xiàn)日志丟失。那該怎么辦?
Redis 為數(shù)據(jù)的安全性考慮,同樣為 AOF 持久化提供了策略配置,打開(kāi) Redis 配置文件,如下圖所示:
上述配置策略說(shuō)明如下:
- Always:
服務(wù)器每寫(xiě)入一個(gè)命令,就調(diào)用一次 fsync函數(shù),將緩沖區(qū)里面的命令寫(xiě)入到硬盤(pán)。
這種模式下,服務(wù)器出現(xiàn)故障,也不會(huì)丟失任何已經(jīng)成功執(zhí)行的命令數(shù)據(jù),但是其執(zhí)行速度較慢; - Everysec(默認(rèn)):
服務(wù)器每一秒調(diào)用一次 fsync 函數(shù),將緩沖區(qū)里面的命令寫(xiě)入到硬盤(pán)。
這種模式下,服務(wù)器出現(xiàn)故障,最多只丟失一秒鐘內(nèi)的執(zhí)行的命令數(shù)據(jù),通常都使用它作為 AOF 配置策略; - No:
服務(wù)器不主動(dòng)調(diào)用 fsync 函數(shù),由操作系統(tǒng)決定何時(shí)將緩沖區(qū)里面的命令寫(xiě)入到硬盤(pán)。
這種模式下,服務(wù)器遭遇意外停機(jī)時(shí),丟失命令的數(shù)量是不確定的,所以這種策略,不確定性較大,不安全。
注意:Linux 系統(tǒng)的 fsync() 函數(shù)可以將指定文件的內(nèi)容從內(nèi)核緩存刷到硬盤(pán)中。
由于是 fsync 是磁盤(pán) IO 操作,所以它很慢!如果 Redis 執(zhí)行一條指令就要 fsync 一次(Always),那么 Redis 高性能將嚴(yán)重受到影響。
在生產(chǎn)環(huán)境的服務(wù)器中,Redis 通常是每隔 1s 左右執(zhí)行一次 fsync 操作
( Everysec),這樣既保持了高性能,也讓數(shù)據(jù)盡可能的少丟失。最后一種策略(No),讓操作系統(tǒng)來(lái)決定何時(shí)將數(shù)據(jù)同步到磁盤(pán),這種策略存在許多不確定性,所以不建議使用。
(3)重寫(xiě)機(jī)制
Redis 在長(zhǎng)期運(yùn)行的過(guò)程中,aof 文件會(huì)越變?cè)介L(zhǎng)。如果機(jī)器宕機(jī)重啟,“重演”整個(gè) aof 文件會(huì)非常耗時(shí),導(dǎo)致長(zhǎng)時(shí)間 Redis 無(wú)法對(duì)外提供服務(wù)。因此就需要對(duì) aof 文件做一下“瘦身”運(yùn)動(dòng)。
為了讓 aof 文件的大小控制在合理的范圍內(nèi),Redis 提供了 AOF 重寫(xiě)機(jī)制,手動(dòng)執(zhí)行BGREWRITEAOF
命令,開(kāi)始重寫(xiě) aof 文件,如下所示:
127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started
通過(guò) bgrewriteaof
操作后,服務(wù)器會(huì)生成一個(gè)新的 aof 文件,該文件具有以下特點(diǎn):
- 新的 aof 文件記錄的數(shù)據(jù)庫(kù)數(shù)據(jù)和原 aof 文件記錄的數(shù)據(jù)庫(kù)數(shù)據(jù)完全一致;
- 新的 aof 文件會(huì)使用盡可能少的命令來(lái)記錄數(shù)據(jù)庫(kù)數(shù)據(jù),因此新的 aof 文件的體積會(huì)小很多;
- AOF 重寫(xiě)期間,服務(wù)器不會(huì)被阻塞,它可以正常處理客戶端發(fā)送的命令。
- 即使 Bgrewriteaof 執(zhí)行失敗,也不會(huì)有任何數(shù)據(jù)丟失,因?yàn)榕f的 AOF 文件在 Bgrewriteaof 成功之前不會(huì)被修改
重寫(xiě)機(jī)制AOF文件對(duì)比:
(4)自動(dòng)觸發(fā)AOF重寫(xiě)
Redis 為自動(dòng)觸發(fā) AOF 重寫(xiě)功能,提供了相應(yīng)的配置策略。如下所示:修改 Redis 配置文件,讓服務(wù)器自動(dòng)執(zhí)行 BGREWRITEAOF
命令。
#默認(rèn)配置項(xiàng) auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb #表示觸發(fā)AOF重寫(xiě)的最小文件體積,大于或等于64MB自動(dòng)觸發(fā)。
該配置項(xiàng)表示:觸發(fā)重寫(xiě)所需要的 aof 文件體積百分比,只有當(dāng) aof 文件的增量大于 100% 時(shí)才進(jìn)行重寫(xiě),也就是大一倍。比如,第一次重寫(xiě)時(shí)文件大小為 64M,那么第二次觸發(fā)重寫(xiě)的體積為 128M,第三次重寫(xiě)為 256M,以此類推。如果將百分比值設(shè)置為 0 就表示關(guān)閉 AOF 自動(dòng)重寫(xiě)功能。
(5)整個(gè)下來(lái)運(yùn)行流程如下:
客戶端的請(qǐng)求寫(xiě)命令會(huì)被append追加到AOF緩沖區(qū)內(nèi)
AOF緩沖區(qū)會(huì)根據(jù)AOF持久化策略[always,everysec,no]將操作sync同步到磁盤(pán)的AOF文件中
AOF文件大小超過(guò)重寫(xiě)策略或手動(dòng)重寫(xiě)時(shí),會(huì)對(duì)AOF文件進(jìn)行重寫(xiě)(rewrite),壓縮AOF文件容量redis服務(wù)器重啟時(shí),會(huì)重新load加載AOF文件中的寫(xiě)操作達(dá)到數(shù)據(jù)恢復(fù)的目的
2、AOF配置
AOF默認(rèn)不開(kāi)啟,可以在 redis.conf 文件中對(duì)AOF進(jìn)行配置開(kāi)啟:
appendonly no # 是否開(kāi)啟AOF,yes:開(kāi)啟,no:不開(kāi)啟,默認(rèn)為no appendfilename "appendonly.aof" # aof文件名稱,默認(rèn)為appendonly.aof dir ./ # aof文件所在目錄,默認(rèn)./,表示執(zhí)行啟動(dòng)命令時(shí)所在的目錄
3、AOF的備份恢復(fù)
AOF的備份機(jī)制和性能雖然和RDB不同,但是備份和恢復(fù)的操作同RDB一樣,都是拷貝備份文件,需要恢復(fù)時(shí)再拷貝到Redis工作目錄下,啟動(dòng)系統(tǒng)即加載。
正?;謴?fù)
- 修改默認(rèn)的appendonly no,改為yes
- 將有數(shù)據(jù)的aof文件復(fù)制一份保存到對(duì)應(yīng)的目錄(查看目錄:config get dir)
- 恢復(fù):重啟redis然后重新加載
異?;謴?fù)
- 修改默認(rèn)的appendonly no,改為yes
- 如遇到aof文件損壞,通過(guò)
redis-check-aof --fix appendonly.aof
進(jìn)行恢復(fù),appendonly.aof是文件名
4、重寫(xiě)流程
- 手動(dòng)執(zhí)行
bgrewriteaof
命令觸發(fā)重寫(xiě),判斷是否當(dāng)前有bgfsave
或bgrewriteaof
在運(yùn)行,如果有,則等待該命令結(jié)束后再繼續(xù)執(zhí)行 - 主進(jìn)程fork出子進(jìn)程執(zhí)行重寫(xiě)操作,保證主進(jìn)程不會(huì)阻塞
- 子進(jìn)程遍歷redis內(nèi)存中的數(shù)據(jù)到臨時(shí)文件,客戶端的寫(xiě)請(qǐng)求同時(shí)寫(xiě)入aof_buf緩沖區(qū)和aof_rewrite_buf重寫(xiě)緩沖區(qū)保證原AOF文件完整性以及新AOF文件生成期間的新的數(shù)據(jù)修改動(dòng)作不會(huì)丟失
- 子進(jìn)程寫(xiě)完新的AOF文件后,向主進(jìn)程發(fā)送信號(hào),父進(jìn)程更新統(tǒng)計(jì)信息
- 主進(jìn)程把a(bǔ)of_rewrite_buf中的數(shù)據(jù)寫(xiě)入到新的AOF文件
- 使用新的AOF文件覆蓋舊的AOF文件,完成AOF重寫(xiě)
no-appendfsync-on-rewrite:重寫(xiě)時(shí),不會(huì)執(zhí)行appendfsync操作
該參數(shù)表示在正在進(jìn)行AOF重寫(xiě)時(shí)不會(huì)將AOF緩沖區(qū)中的數(shù)據(jù)同步到舊的AOF文件磁盤(pán)
,也就是說(shuō)在進(jìn)行AOF重寫(xiě)的時(shí)候,如果此時(shí)有寫(xiě)操作進(jìn)來(lái),此時(shí)寫(xiě)操作的命令會(huì)放在aof_buf緩存中(內(nèi)存中),而不會(huì)將其追加到舊的AOF文件中,這么做是為了避免同時(shí)寫(xiě)舊的AOF文件和新的AOF文件對(duì)磁盤(pán)產(chǎn)生的壓力。
默認(rèn)是ON,表示關(guān)閉,即在AOF重寫(xiě)時(shí),會(huì)對(duì)AOF緩沖區(qū)中的數(shù)據(jù)做同步磁盤(pán)操作
,這在很大程度上保證了數(shù)據(jù)的安全性。但是遇到重寫(xiě)操作,可能會(huì)發(fā)生阻塞。(數(shù)據(jù)安全,但是性能降低)如果no-appendfsync-on-rewrite為yes,不寫(xiě)入aof文件,只寫(xiě)入緩存
,用戶請(qǐng)求不會(huì)阻塞,但是在這段時(shí)間如果宕機(jī)會(huì)丟失這段時(shí)間的緩存數(shù)據(jù)。(降低數(shù)據(jù)安全性,提高性能)
但在數(shù)據(jù)量很大的場(chǎng)景,因?yàn)閮烧叨紩?huì)消耗磁盤(pán)IO,對(duì)磁盤(pán)的影響較大,可以將其設(shè)置為“yes”減輕磁盤(pán)壓力,但在極端情況下可能丟失整個(gè)AOF重寫(xiě)期間的數(shù)據(jù)。
5、AOF優(yōu)缺點(diǎn)
優(yōu)勢(shì):
- 備份機(jī)制更穩(wěn)健,丟失數(shù)據(jù)概率更低
- 可讀的日志文本,通過(guò)操作AOF文件,可以處理誤操作
劣勢(shì):
- 比RDB占用更多的磁盤(pán)空間
- 恢復(fù)備份速度要慢
- 每次讀寫(xiě)都同步的話,有一定的性能壓力
- 存在個(gè)別bug,造成不能恢復(fù)
總結(jié):
- AOF文件是一個(gè)只進(jìn)行追加的日志文件
- Redis可以在AOF文件體積變得過(guò)大時(shí),自動(dòng)地在后臺(tái)對(duì)AOF文件進(jìn)行重寫(xiě)
- AOF文件有序地保存了對(duì)數(shù)據(jù)庫(kù)執(zhí)行的所有寫(xiě)入操作,這些寫(xiě)入操作以redis協(xié)議的格式保存,因此AOF文件的內(nèi)容非常容易被人讀懂,對(duì)文件進(jìn)行分析也很輕松。
- 對(duì)于相同的數(shù)據(jù)集來(lái)說(shuō),AOF文件的體積通常要大于RDB文件的體積
- 根據(jù)所使用的fsync策略,AOF的速度可能會(huì)慢于RDB
四、AOF和RDB對(duì)比
官方推薦2個(gè)都啟用。
如果對(duì)數(shù)據(jù)不敏感,可以單獨(dú)用RDB。
不建議單獨(dú)使用AOF,因?yàn)榭赡軙?huì)出現(xiàn)BUG。
如果只是做純內(nèi)存緩存,可以都不用。
五、AOF和RDB官網(wǎng)建議
- RDB持久化方式能夠在指定的時(shí)間間隔對(duì)你的數(shù)據(jù)進(jìn)行快照存儲(chǔ)
- AOF持久化方式記錄每次對(duì)服務(wù)器寫(xiě)的操作,當(dāng)服務(wù)器重啟的時(shí)候會(huì)重新執(zhí)行這些命令來(lái)恢復(fù)原始數(shù)據(jù),AOF命令以redis協(xié)議追加保存每次寫(xiě)的操作到AOF文件末尾
- Redis還能對(duì)AOF文件進(jìn)行后臺(tái)重寫(xiě),使得AOF文件的體積不至于過(guò)大
- 只做緩存:如果你只希望你的數(shù)據(jù)在服務(wù)器運(yùn)行的時(shí)候存在,你也可以不使用任何持久化方式
- 同時(shí)開(kāi)啟兩種持久化方式:在這種情況下,當(dāng)redis重啟的時(shí)候會(huì)優(yōu)先載入AOF文件來(lái)恢復(fù)原始的數(shù)據(jù),因?yàn)樵谕ǔG闆r下AOF文件保存的數(shù)據(jù)集要比RDB文件保存的數(shù)據(jù)集要完整
- RDB的數(shù)據(jù)不實(shí)時(shí),同時(shí)使用兩者時(shí)服務(wù)器重啟也只會(huì)找AOF文件,那要是只用AOF呢?
- 建議不要,因?yàn)镽DB更適合用于備份數(shù)據(jù)庫(kù),快速重啟,而且不會(huì)有AOF可能潛在的bug,留著作為一個(gè)萬(wàn)一的手段
- 性能建議
- 因?yàn)镽DB文件只用作后備用途,建議只在Slave上持久化RDB文件,而且只要15分鐘備份一次就夠了,只保留 save 900 1 這一條
- 如果使用AOF,好處是在最惡劣的情況下也只會(huì)丟失不超過(guò)兩秒數(shù)據(jù),啟動(dòng)腳本較簡(jiǎn)單只load自己的AOF文件就可以了
- AOF的代價(jià),一是帶來(lái)持續(xù)的IO,二是AOF rewrite的最后將rewrite過(guò)程中產(chǎn)生的新數(shù)據(jù)(aof_rewrite_buf)寫(xiě)到文件造成的阻塞幾乎是不可避免的
- 只要硬盤(pán)許可,應(yīng)該盡量減少AOF rewrite的頻率,AOF重寫(xiě)的基數(shù)大小默認(rèn)值64M(autoaof-rewrite-min-size)太小了,可以設(shè)置到5G以上
- 默認(rèn)超過(guò)原大小100%(auto-aof-rewrite-percentage)大小時(shí)重寫(xiě)可以改到適當(dāng)?shù)臄?shù)值。
通常 Redis 的主節(jié)點(diǎn)是不會(huì)進(jìn)行持久化操作,持久化操作主要在從節(jié)點(diǎn)進(jìn)行。
從節(jié)點(diǎn)是備份節(jié)點(diǎn),沒(méi)有來(lái)自客戶端請(qǐng)求的壓力,它的操作系統(tǒng)資源往往比較充沛。
但是如果出現(xiàn)網(wǎng)絡(luò)分區(qū),從節(jié)點(diǎn)長(zhǎng)期連不上主節(jié)點(diǎn),就會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,特別是在網(wǎng)絡(luò)分區(qū)出現(xiàn)的情況下又不小心主節(jié)點(diǎn)宕機(jī)了,那么數(shù)據(jù)就會(huì)丟失,所以在生產(chǎn)環(huán)境要做好實(shí)時(shí)監(jiān)控工作,保證網(wǎng)絡(luò)暢通或者能快速修復(fù)。另外還應(yīng)該再增加一個(gè)從節(jié)點(diǎn)以降低網(wǎng)絡(luò)分區(qū)的概率,只要有一個(gè)從節(jié)點(diǎn)數(shù)據(jù)同步正常,數(shù)據(jù)也就不會(huì)輕易丟失。
六、Redis 4.0 混合持久化
1、混合持久化原理
重啟 Redis 時(shí),我們很少使用 rdb 來(lái)恢復(fù)內(nèi)存狀態(tài),因?yàn)闀?huì)丟失大量數(shù)據(jù)。我們通常使用 AOF 日志重放,但是重放 AOF 日志性能相對(duì) rdb 來(lái)說(shuō)要慢很多,這樣在 Redis 實(shí)例很大的情況下,啟動(dòng)需要花費(fèi)很長(zhǎng)的時(shí)間。
Redis 4.0 為了解決這個(gè)問(wèn)題,帶來(lái)了一個(gè)新的持久化選項(xiàng)——混合持久化。將 rdb 文件的內(nèi)容和增量的 AOF 日志文件存在一起。這里的 AOF 日志不再是全量的日志,而是自持久化開(kāi)始到持久化結(jié)束的這段時(shí)間發(fā)生的增量 AOF 日志,通常這部分 AOF 日志很小。
于是在 Redis 重啟的時(shí)候,可以先加載 rdb 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重啟效率因此大幅得到提升。
混合持久化的加載流程如下:
2、混合持久化配置
在redis的配置文件當(dāng)中有一個(gè)aof-use-rdb-preamble
參數(shù)來(lái)開(kāi)啟 混合持久化,默認(rèn)是yes
開(kāi)啟的?;旌铣志没Y(jié)合了 RDB 和 AOF 的優(yōu)點(diǎn),Redis 5.0 默認(rèn)是開(kāi)啟的。
3、混合持久化優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 混合持久化結(jié)合了 RDB 和 AOF 持久化的優(yōu)點(diǎn),開(kāi)頭為 RDB 的格式,使得 Redis 可以更快的啟動(dòng),同時(shí)結(jié)合 AOF的優(yōu)點(diǎn),有減低了大量數(shù)據(jù)丟失的風(fēng)險(xiǎn)。
缺點(diǎn):
- AOF 文件中添加了 RDB 格式的內(nèi)容,使得 AOF 文件的可讀性變得很差;
- 兼容性差,如果開(kāi)啟混合持久化,那么此混合持久化 AOF 文件,就不能用在 Redis 4.0 之前版本了。
以上就是Redis的持久化詳解的詳細(xì)內(nèi)容,更多關(guān)于Redis 持久化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
redis lua腳本實(shí)戰(zhàn)秒殺和減庫(kù)存的實(shí)現(xiàn)
本文主要是學(xué)習(xí)一下redis lua腳本的編寫(xiě),以及在redisson這個(gè)redis客戶端中是怎樣使用的,實(shí)戰(zhàn)一下秒殺場(chǎng)景redis減庫(kù)存lua腳本的編寫(xiě),并偽真實(shí)環(huán)境壓測(cè)查看效果。感興趣的可以了解一下2021-11-11redis?消息隊(duì)列完成秒殺過(guò)期訂單處理方法(一)
這篇文章主要介紹了redis?消息隊(duì)列完成秒殺過(guò)期訂單處理方法,包括redis?消息通知處理代金券過(guò)期問(wèn)題–失效問(wèn)題的分析,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07關(guān)于Redis未授權(quán)訪問(wèn)的問(wèn)題
這篇文章主要介紹了Redis未授權(quán)訪問(wèn)的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07用Redis實(shí)現(xiàn)微博關(guān)注關(guān)系
在微博中,每一個(gè)用戶都會(huì)有一個(gè)關(guān)注列表,一個(gè)粉絲列表。用戶可以查看自己的關(guān)注,粉絲列表,也可以查看別人的關(guān)注,粉絲列表。并且,要展示列表里每個(gè)人與當(dāng)前查看者的關(guān)注狀態(tài)。2015-09-09Windows環(huán)境下查看、添加、修改redis數(shù)據(jù)庫(kù)的密碼兩種方式
在Windows系統(tǒng)上設(shè)置Redis密碼的過(guò)程與Linux系統(tǒng)類似,但需注意幾個(gè)關(guān)鍵步驟以確保正確配置,這篇文章主要給大家介紹了關(guān)于Windows環(huán)境下查看、添加、修改redis數(shù)據(jù)庫(kù)的密碼兩種方式,需要的朋友可以參考下2024-07-07如何使用redis中的zset實(shí)現(xiàn)滑動(dòng)窗口限流
滑動(dòng)窗口限流是一種常見(jiàn)的流量控制方法,它限制了在一定時(shí)間窗口內(nèi)的請(qǐng)求數(shù)量,下面是使用Redis ZSet實(shí)現(xiàn)滑動(dòng)窗口限流的一個(gè)簡(jiǎn)單示例,需要的朋友可以參考下2023-09-09Redis壓縮列表的設(shè)計(jì)與實(shí)現(xiàn)
壓縮列表(Ziplist)是 Redis 為了節(jié)省內(nèi)存而設(shè)計(jì)的一種緊湊型數(shù)據(jù)結(jié)構(gòu),主要用于存儲(chǔ)長(zhǎng)度較短且數(shù)量較少的元素集合,本文給大家介紹了Redis壓縮列表的設(shè)計(jì)與實(shí)現(xiàn),文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-08-08