偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

京東二面:Redis持久化方式有哪些?說(shuō)下各自的優(yōu)缺點(diǎn)?線上環(huán)境如何進(jìn)行配置的?

數(shù)據(jù)庫(kù) Redis
如果存儲(chǔ)在Redis中的數(shù)據(jù)相對(duì)不敏感或能便捷地重新生成,可以選擇暫時(shí)關(guān)閉持久化功能,以減少資源消耗。這樣即使偶發(fā)數(shù)據(jù)丟失,也能通過(guò)其他機(jī)制迅速恢復(fù)數(shù)據(jù)。比如一些數(shù)據(jù)相對(duì)于DB來(lái)說(shuō),并沒(méi)有經(jīng)過(guò)一些特殊處理,可以直接從DB中進(jìn)行恢復(fù),相當(dāng)于直接在DB做備份。

引言

Redis作為一款高性能的鍵值存儲(chǔ)系統(tǒng),廣泛應(yīng)用于緩存、消息隊(duì)列、會(huì)話存儲(chǔ)等多種場(chǎng)景,成為提升應(yīng)用性能的關(guān)鍵組件。作為內(nèi)存數(shù)據(jù)庫(kù),它存儲(chǔ)在內(nèi)存中的數(shù)據(jù)在服務(wù)器重啟或發(fā)生意外崩潰時(shí)將會(huì)丟失。所以需要持久化機(jī)制能夠?qū)?nèi)存中的數(shù)據(jù)保存到磁盤(pán)上,從而在Redis服務(wù)停止或重啟后能夠恢復(fù)數(shù)據(jù),保證數(shù)據(jù)的安全性。

在實(shí)際開(kāi)發(fā)中的一些通用方案是業(yè)務(wù)數(shù)據(jù)最終都保存在DB中,所以也可以從數(shù)據(jù)庫(kù)中恢復(fù)Redis數(shù)據(jù)。但是這種方式,會(huì)造成數(shù)據(jù)庫(kù)的性能瓶頸,特別是在大量Redis數(shù)據(jù)需要恢復(fù)的時(shí)候。并且Redis中緩存的數(shù)據(jù),會(huì)經(jīng)過(guò)一些特殊的處理,跟DB中表數(shù)據(jù)可能會(huì)不一致,所以從DB中恢復(fù)Redis數(shù)據(jù)還需要一些特殊的業(yè)務(wù)梳理。

所以就需要從Redis自身出發(fā)會(huì)解決這個(gè)問(wèn)題,Redis設(shè)計(jì)了兩種主要的持久化機(jī)制:RDB和AOF。實(shí)際上,對(duì)于持久化方案,官方文檔中給出了三種方式:RDB,AOF,RDB+AOF。

圖片圖片

關(guān)于Redis持久化機(jī)制的官方文檔:Redis persistence | Docs

Redis持久化方式

Redis提供了兩種核心的持久化策略:RDB(快照)和AOF(僅追加日志),隨著Redis版本的演進(jìn),還引入了混合持久化的方式,進(jìn)一步優(yōu)化了Redis的持久化。

RDB

RDB,即Redis Database,是一種快照式持久化方式,它通過(guò)定期創(chuàng)建數(shù)據(jù)集的快照來(lái)實(shí)現(xiàn)數(shù)據(jù)的持久存儲(chǔ)。在預(yù)設(shè)條件(如時(shí)間間隔、鍵值變化次數(shù))滿足時(shí),Redis會(huì)生成當(dāng)前內(nèi)存中所有數(shù)據(jù)的備份文件。當(dāng)Redis服務(wù)需要重新啟動(dòng)時(shí),可以直接加載這些RDB文件,從而快速恢復(fù)數(shù)據(jù)。由于RDB文件是二進(jìn)制格式,加載速度通常較快。生成快照有自動(dòng)觸發(fā)和手動(dòng)觸發(fā)兩種方式。

自動(dòng)觸發(fā)

Redis會(huì)將數(shù)據(jù)集的快照保存到名為dump.rdb的二進(jìn)制文件中,保存到磁盤(pán)上。我們可以通過(guò)Redis配置(redis.conf文件),使其在數(shù)據(jù)集中至少有M個(gè)(changes)更改時(shí),每N秒(seconds)自動(dòng)保存一次數(shù)據(jù)集。

save <seconds> <changes> [<seconds> <changes> ...]
# 生成的rdb文件名稱(chēng)
dbfilename dump.rdb

# rdb文件保存路徑,可自定義
dir ./

# rdb快照保存配置
save 3600 1 300 100 60 10000

# 如果至少進(jìn)行了1次更改,那么在3600秒(1小時(shí))后保存;
# 如果至少進(jìn)行了100次更改,那么在300秒(5分鐘)后保存;
# 如果至少進(jìn)行了10000次更改,那么在60秒后保存。

# 關(guān)閉RDB快照
save ""

當(dāng)Redis服務(wù)正常關(guān)閉時(shí),如果沒(méi)有啟用AOF(Append Only File)持久化,它也會(huì)執(zhí)行一次RDB快照,確保數(shù)據(jù)被保存到磁盤(pán)上。

手動(dòng)觸發(fā)

我們還可以通過(guò)調(diào)用SAVE或BGSAVE命令來(lái)手動(dòng)觸發(fā)快照保存。這兩個(gè)命令的區(qū)別在于執(zhí)行數(shù)據(jù)持久化操作時(shí)是否阻塞主線程。

SAVE命令

當(dāng)執(zhí)行SAVE命令時(shí),Redis會(huì)直接調(diào)用rdbSave函數(shù)來(lái)創(chuàng)建數(shù)據(jù)快照,并將當(dāng)前數(shù)據(jù)集寫(xiě)入到磁盤(pán)上的RDB文件中。這是一個(gè)同步操作,在保存過(guò)程期間,Redis的主進(jìn)程會(huì)被阻塞,無(wú)法處理任何其他客戶(hù)端的請(qǐng)求,直到整個(gè)保存操作完成。所以,如果數(shù)據(jù)集較大,此操作可能會(huì)導(dǎo)致Redis服務(wù)在較長(zhǎng)時(shí)間內(nèi)無(wú)法響應(yīng),影響服務(wù)的可用性。

BGSAVE命令

使用BGSAVE命令時(shí),Redis會(huì)通過(guò)操作系統(tǒng)fork()調(diào)用創(chuàng)建一個(gè)子進(jìn)程,由這個(gè)子進(jìn)程負(fù)責(zé)執(zhí)行rdbSave函數(shù)和數(shù)據(jù)持久化工作,即創(chuàng)建數(shù)據(jù)快照并寫(xiě)入RDB文件。持久化操作在子進(jìn)程中進(jìn)行,Redis的主進(jìn)程(父進(jìn)程)可以繼續(xù)處理來(lái)自客戶(hù)端的請(qǐng)求,不會(huì)因?yàn)槌志没僮鞫枞?。?dāng)子進(jìn)程完成快照創(chuàng)建后,會(huì)向主進(jìn)程發(fā)送一個(gè)信號(hào),通知任務(wù)完成,然后子進(jìn)程關(guān)閉。

BGSAVE命令執(zhí)行流程BGSAVE命令執(zhí)行流程

具體執(zhí)行流程如下:

1. 當(dāng)Redis客戶(hù)端發(fā)出BGSAVE命令,或者根據(jù)配置規(guī)則自動(dòng)觸發(fā)BGSAVE操作時(shí),持久化進(jìn)程開(kāi)始

2. Redis主進(jìn)程檢查是否有正在進(jìn)行的子進(jìn)程正在執(zhí)行BGSAVE或AOF rewrite操作。如果存在這種操作,為了避免資源競(jìng)爭(zhēng)和數(shù)據(jù)一致性問(wèn)題,主進(jìn)程不會(huì)再次發(fā)起B(yǎng)GSAVE,可能直接返回一個(gè)錯(cuò)誤或忽略此次請(qǐng)求。

3. 如果沒(méi)有其他持久化操作正在進(jìn)行,主進(jìn)程會(huì)執(zhí)行fork()系統(tǒng)調(diào)用來(lái)創(chuàng)建一個(gè)子進(jìn)程。fork()調(diào)用在執(zhí)行時(shí)會(huì)暫時(shí)阻塞主進(jìn)程,直到子進(jìn)程完全創(chuàng)建。這個(gè)過(guò)程中,Redis的內(nèi)存數(shù)據(jù)不會(huì)被復(fù)制,而是通過(guò)操作系統(tǒng)實(shí)現(xiàn)的寫(xiě)時(shí)復(fù)制(Copy-On-Write, COW)機(jī)制共享給子進(jìn)程。

4. 子進(jìn)程開(kāi)始工作,它將內(nèi)存中的數(shù)據(jù)逐步寫(xiě)入到一個(gè)新的臨時(shí)RDB文件中。這個(gè)過(guò)程對(duì)主進(jìn)程是透明的,不會(huì)影響主進(jìn)程處理客戶(hù)端的讀寫(xiě)請(qǐng)求。

5. 當(dāng)所有數(shù)據(jù)寫(xiě)入完畢后,子進(jìn)程會(huì)使用原子操作(通常借助操作系統(tǒng)提供的rename函數(shù))將臨時(shí)RDB文件替換為正式的RDB文件。保證RBD文件的完整性。

6. 完成上述步驟后,子進(jìn)程會(huì)向主進(jìn)程發(fā)送一個(gè)信號(hào),告知BGSAVE操作已完成。

RDB優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

? 快速恢復(fù):RDB文件加載速度非??欤?yàn)樗苯訉?shù)據(jù)載入內(nèi)存而無(wú)需逐條執(zhí)行命令,適合用于快速重啟服務(wù)后的數(shù)據(jù)恢復(fù)。

? 資源占用低:RDB文件(二進(jìn)制文件)通常較小,占用磁盤(pán)空間少,備份和傳輸更加高效。

缺點(diǎn)

? 數(shù)據(jù)丟失風(fēng)險(xiǎn):如果Redis在兩次快照之間崩潰,那么從上一次快照之后的所有數(shù)據(jù)變更將會(huì)丟失。因此,RDB更適合對(duì)數(shù)據(jù)實(shí)時(shí)性要求不高,但重視恢復(fù)速度的場(chǎng)景。

? 無(wú)法進(jìn)行部分恢復(fù):一旦發(fā)生故障,只能整體恢復(fù)到最近一次快照的狀態(tài),無(wú)法選擇性恢復(fù)特定數(shù)據(jù)。

幾個(gè)常見(jiàn)的面試問(wèn)題

? 如果我們的Redis內(nèi)存的數(shù)據(jù)比較大(可能給Redis分配的內(nèi)存較大),我們生成快照保存到磁盤(pán),就會(huì)花費(fèi)的時(shí)間要久一些,如果此時(shí)Redis的主進(jìn)程依然還要在處理一些寫(xiě)數(shù)據(jù)的請(qǐng)求,那么我們?nèi)绾伪WC數(shù)據(jù)一致性呢?

有上述RDB的執(zhí)行流程中可以看出,主進(jìn)程通過(guò)寫(xiě)時(shí)復(fù)制,將數(shù)據(jù)共享給子進(jìn)程。在持久化操作開(kāi)始時(shí),父子進(jìn)程共享相同的內(nèi)存空間,直到任一進(jìn)程嘗試修改數(shù)據(jù)。當(dāng)主進(jìn)程接收到寫(xiě)操作請(qǐng)求并需要修改數(shù)據(jù)時(shí),操作系統(tǒng)會(huì)為被修改的數(shù)據(jù)分配新的內(nèi)存空間,保持原數(shù)據(jù)不變供子進(jìn)程快照使用。即便在快照生成期間有寫(xiě)操作,也能保證快照數(shù)據(jù)反映的是快照操作開(kāi)始那一刻的數(shù)據(jù)狀態(tài),確保了數(shù)據(jù)的一致性。

圖片圖片

? 在生成快照的時(shí)候,Redis服務(wù)跪了,數(shù)據(jù)會(huì)不會(huì)丟失? 在上述BGSAVE命令執(zhí)行流程時(shí),在最后的寫(xiě)入磁盤(pán)時(shí),子進(jìn)程會(huì)使用原子操作將臨時(shí)RDB文件替換為正式的RDB文件,保證RBD文件的完整性。也就是說(shuō)Redis在執(zhí)行BGSAVE命令生成快照時(shí),會(huì)先將數(shù)據(jù)寫(xiě)入到一個(gè)臨時(shí)的RDB文件中,而不是直接覆蓋原有的RDB文件。只有當(dāng)新的快照完全且成功地寫(xiě)入磁盤(pán)之后,才會(huì)用這個(gè)新的快照文件替換掉舊的RDB文件。這一過(guò)程是原子性的,確保了要么新快照完全成功,要么不會(huì)有任何改動(dòng),從而避免了部分寫(xiě)入導(dǎo)致的文件損壞,避免數(shù)據(jù)的丟失。

? 快照的生成時(shí)間間隔是不是越小越好?如何合理的設(shè)置? 對(duì)于RDB生成快照來(lái)做數(shù)據(jù)持久化,就是通過(guò)連續(xù)的生成數(shù)據(jù)快照將數(shù)據(jù)保存到磁盤(pán)。一單服務(wù)發(fā)生故障,那么我們就可以通過(guò)磁盤(pán)上的文件恢復(fù)數(shù)據(jù)。那么,為了防止數(shù)據(jù)丟失,或者數(shù)據(jù)丟失過(guò)多時(shí),我們可以通過(guò)減少時(shí)間間隔來(lái)實(shí)現(xiàn),也就是說(shuō),最好可以一直不停的生成快照,這樣就可以達(dá)到數(shù)據(jù)不丟失的目的。

圖片圖片

如上圖,T0時(shí)刻生成了一次快照,那么在t時(shí)刻時(shí)發(fā)生了一次數(shù)據(jù)修改寫(xiě)入,在寫(xiě)入后到生成下一次快照之前,發(fā)生了故障,那么我們恢復(fù)數(shù)據(jù)時(shí),因?yàn)門(mén)0+t時(shí)刻的快照還沒(méi)生成,數(shù)據(jù)恢復(fù)時(shí)只能使用T0時(shí)刻的快照,那么在t時(shí)刻發(fā)生的數(shù)據(jù)寫(xiě)入就會(huì)丟失。所以t時(shí)刻的間隔如果變的更小,就會(huì)多生成快照,就有很大的幾率減少數(shù)據(jù)丟失的。

那么是不是說(shuō)這個(gè)生成快照的間隔越小越好,甚至說(shuō)1秒生成一次快照?因?yàn)閺腂GSAVE的執(zhí)行流程上看,它是通過(guò)fork一個(gè)子進(jìn)程去實(shí)現(xiàn)快照的生成,并不會(huì)阻塞主進(jìn)程的數(shù)據(jù)寫(xiě)入。

事實(shí)上,這種說(shuō)法是錯(cuò)誤的。理論上,縮短快照間隔可以減少數(shù)據(jù)丟失的風(fēng)險(xiǎn),因?yàn)橐坏┫到y(tǒng)崩潰,可以恢復(fù)到更接近崩潰時(shí)間點(diǎn)的數(shù)據(jù)狀態(tài)。但是,過(guò)于緊密的快照間隔會(huì)引發(fā)大量的磁盤(pán)I/O操作,可能導(dǎo)致數(shù)據(jù)寫(xiě)操作堆積,反而影響數(shù)據(jù)的一致性。

并且,雖然Redis使用BGSAVE命令在子進(jìn)程中生成快照,避免了主線程的長(zhǎng)時(shí)間阻塞,但是fork子進(jìn)程的操作本身是阻塞的,并且內(nèi)存越大,fork操作所需的時(shí)間越長(zhǎng)。頻繁的fork會(huì)導(dǎo)致服務(wù)在短時(shí)間內(nèi)頻繁阻塞,影響響應(yīng)速度。

那么,如果我們可以只對(duì)增量的數(shù)據(jù)進(jìn)行快照保存,在第一次進(jìn)行全量的快照保存后,后續(xù)的快照都只對(duì)增量的數(shù)據(jù)(其實(shí)這個(gè)比較很好理解,這種方案我們也很常見(jiàn),比如我們?cè)趯?duì)接一些第三方系統(tǒng)時(shí),在拉取數(shù)據(jù)時(shí),我們?cè)诘谝淮稳坷ズ?,后面的?shù)據(jù)都只會(huì)拉去變化的數(shù)據(jù))。那么對(duì)于增量的數(shù)據(jù),首先我們要知道那些數(shù)據(jù)變化了,此時(shí),就需要Redis的另外一種機(jī)制:AOF了。

AOF

AOF(Append Only File)持久化是一種以日志形式記錄每次寫(xiě)操作的方式,以此來(lái)保證數(shù)據(jù)的持久性。與RDB不同,它提供了更高的數(shù)據(jù)完整性保障,因?yàn)槠溆涗浟藦腞edis啟動(dòng)以來(lái)的所有寫(xiě)操作,理論上可以做到數(shù)據(jù)零丟失。

每當(dāng)有寫(xiě)命令(如SET、HSET等)被執(zhí)行時(shí),Redis就會(huì)將該命令以明文形式追加到AOF文件的末尾。這意味著AOF文件隨著時(shí)間推移會(huì)不斷增長(zhǎng),記錄著Redis服務(wù)器上的所有數(shù)據(jù)修改歷史。

并且AOF采用的是一種"寫(xiě)后日志"機(jī)制,即Redis在處理寫(xiě)命令時(shí),先執(zhí)行寫(xiě)操作,將數(shù)據(jù)變更寫(xiě)入內(nèi)存,然后才將該操作命令追加到AOF日志文件中。

寫(xiě)后日志這種機(jī)制與一些數(shù)據(jù)庫(kù)系統(tǒng)采用的“預(yù)寫(xiě)日志”策略恰好相反,后者是在實(shí)際數(shù)據(jù)寫(xiě)入前先記錄日志。

為什么采用寫(xiě)后日志?

1. 性能考慮:通過(guò)先執(zhí)行寫(xiě)命令,Redis可以更快地響應(yīng)客戶(hù)端,因?yàn)閷?xiě)入內(nèi)存的速度遠(yuǎn)快于寫(xiě)入磁盤(pán)。這樣可以減少客戶(hù)端等待時(shí)間。

2. 簡(jiǎn)化實(shí)現(xiàn):寫(xiě)后日志避免了在記錄日志之前對(duì)命令進(jìn)行語(yǔ)法檢查的需要。如果先記錄日志再執(zhí)行命令,錯(cuò)誤的命令也可能被記錄,導(dǎo)致在使用日志恢復(fù)數(shù)據(jù)時(shí)出現(xiàn)問(wèn)題。而在Redis中,因?yàn)槊钜呀?jīng)執(zhí)行成功,所以寫(xiě)入日志的命令都是已驗(yàn)證過(guò)的,可以安全重放。

3. 簡(jiǎn)化恢復(fù)邏輯:在Redis重啟時(shí),通過(guò)重放AOF日志中的命令來(lái)恢復(fù)數(shù)據(jù)狀態(tài),由于這些命令都是曾經(jīng)成功執(zhí)行過(guò)的,理論上可以無(wú)誤地重建內(nèi)存數(shù)據(jù)結(jié)構(gòu),降低了數(shù)據(jù)恢復(fù)的復(fù)雜度。

當(dāng)然這中機(jī)制也存在著一些潛在風(fēng)險(xiǎn),比如數(shù)據(jù)丟失風(fēng)險(xiǎn),如果在命令執(zhí)行后、但未記錄到AOF日志前發(fā)生故障,這部分?jǐn)?shù)據(jù)更新將丟失。

AOF實(shí)現(xiàn)流程

1. 命令追加(Append): 當(dāng)Redis服務(wù)器配置開(kāi)啟了AOF持久化功能后,每當(dāng)執(zhí)行一個(gè)寫(xiě)命令(如SET、HSET、LPUSH等),服務(wù)器并不會(huì)立即寫(xiě)入到磁盤(pán),而是先將這條命令以Redis協(xié)議的格式追加到內(nèi)存中的一個(gè)緩沖區(qū),即aof_buf。

這樣做是為了減少直接磁盤(pán)I/O的頻率,提高寫(xiě)入命令的處理速度。

2. 文件寫(xiě)入(Write): 緩沖區(qū)中的內(nèi)容并不會(huì)一直停留,而是會(huì)按照一定的策略(由配置項(xiàng)appendfsync控制)被寫(xiě)入到AOF文件中。AOF提供了三種同步策略來(lái)控制命令寫(xiě)入AOF文件:

? always:每個(gè)寫(xiě)命令都會(huì)立即同步到磁盤(pán),最安全但性能消耗最大。

? everysec(默認(rèn)):每秒執(zhí)行一次fsync操作,平衡了數(shù)據(jù)安全性與性能。最多丟失一秒的數(shù)據(jù)。

? no:完全依賴(lài)于操作系統(tǒng)來(lái)決定何時(shí)將數(shù)據(jù)寫(xiě)入磁盤(pán),性能最佳但可能丟失一秒內(nèi)的數(shù)據(jù)。

3. 文件同步(Sync): 文件同步操作是將內(nèi)存中已寫(xiě)入AOF文件的數(shù)據(jù)真正持久化到磁盤(pán)上。上述寫(xiě)入AOF文件策略的不同,同步操作的時(shí)機(jī)也會(huì)有所不同。文件同步系統(tǒng)調(diào)用是同步操作的核心,它確保了緩沖區(qū)中的數(shù)據(jù)被物理寫(xiě)入磁盤(pán),從而在硬件故障時(shí)也能保證數(shù)據(jù)不丟失。

AOF重寫(xiě)機(jī)制

隨著時(shí)間的推移,AOF文件會(huì)因?yàn)椴粩嘧芳訉?xiě)命令而逐漸增大,這不僅占用大量磁盤(pán)空間,還會(huì)影響數(shù)據(jù)恢復(fù)的速度。AOF重寫(xiě)機(jī)制通過(guò)生成一個(gè)更緊湊的新AOF文件來(lái)解決這個(gè)問(wèn)題,新文件僅包含重建當(dāng)前數(shù)據(jù)集狀態(tài)所需的最小命令集合,從而替代原有的龐大AOF文件。

AOF重寫(xiě)可以通過(guò)手動(dòng)執(zhí)行BGREWRITEAOF命令來(lái)觸發(fā),也可以通過(guò)配置自動(dòng)觸發(fā)。自動(dòng)觸發(fā)的條件通常是AOF文件大小增長(zhǎng)到一定比例(如通過(guò)auto-aof-rewrite-percentage配置)或達(dá)到一定的最小尺寸(如通過(guò)auto-aof-rewrite-min-size配置)。

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

類(lèi)似RDB的BGSAVE命令的工作機(jī)制,當(dāng)重寫(xiě)命令發(fā)出后,Redis會(huì)通過(guò)fork()系統(tǒng)調(diào)用創(chuàng)建一個(gè)子進(jìn)程。子進(jìn)程開(kāi)始遍歷Redis內(nèi)存中的數(shù)據(jù)結(jié)構(gòu),對(duì)每個(gè)鍵值對(duì)執(zhí)行相應(yīng)最少的寫(xiě)命令(如SET、HMSET等),將這些命令寫(xiě)入到一個(gè)新的臨時(shí)AOF文件中。這個(gè)過(guò)程中,子進(jìn)程不會(huì)處理任何網(wǎng)絡(luò)請(qǐng)求,也不會(huì)影響主進(jìn)程處理客戶(hù)端命令的能力。

與RDB不同的是,在子進(jìn)程重寫(xiě)期間,主進(jìn)程會(huì)繼續(xù)接收和處理客戶(hù)端的寫(xiě)請(qǐng)求。為了避免這些新命令丟失,主進(jìn)程會(huì)將它們追加到一個(gè)內(nèi)存緩沖區(qū)(AOF重寫(xiě)緩沖區(qū))中。

一旦子進(jìn)程完成重寫(xiě),會(huì)將臨時(shí)AOF文件替換掉舊的AOF文件。(為了保證數(shù)據(jù)一致性,這一過(guò)程通常需要原子操作。)在新AOF文件替換舊文件后,主進(jìn)程會(huì)將之前累積在AOF重寫(xiě)緩沖區(qū)中的命令追加到新AOF文件的末尾,確保所有數(shù)據(jù)變更都得到記錄。

AOF重寫(xiě)流程AOF重寫(xiě)流程

如何配置AOF

默認(rèn)情況下,Redis是沒(méi)有開(kāi)啟AOF的,可以通過(guò)配置redis.conf文件來(lái)開(kāi)啟AOF持久化。

# 開(kāi)啟AOF,默認(rèn)為no,關(guān)閉
appendonly yes

# AOF文件名
appendfilename "appendonly.aof"

# 控制AOF fsync策略
appendfsync everysec

# 文件重寫(xiě)策略
aof-rewrite-incremental-fsync yes

# AOF重寫(xiě)觸發(fā)條件,當(dāng)AOF文件增長(zhǎng)到上一次重寫(xiě)后大小的百分比時(shí)觸發(fā)
auto-aof-rewrite-percentage 100

# 觸發(fā)重寫(xiě)的最小AOF文件大小
auto-aof-rewrite-min-size 64mb

# 在Redis啟動(dòng)時(shí)如何加載AOF文件,默認(rèn)為yes
aof-load-truncated yes

# aof重寫(xiě)期間是否同步
no-appendfsync-on-rewrite no

AOF的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

? 幾乎可以實(shí)現(xiàn)數(shù)據(jù)的零丟失,即使在服務(wù)器崩潰后也能恢復(fù)到最新?tīng)顟B(tài)。

? 通過(guò)重寫(xiě)機(jī)制可以有效控制文件大小,且在極端情況下,即使AOF文件損壞,也往往能通過(guò)跳過(guò)錯(cuò)誤命令來(lái)恢復(fù)大部分?jǐn)?shù)據(jù)。

缺點(diǎn)

? AOF文件會(huì)不斷膨脹,占用大量磁盤(pán)空間。

? AOF在服務(wù)器重啟時(shí)需要逐條執(zhí)行命令來(lái)恢復(fù)數(shù)據(jù),這會(huì)消耗更多時(shí)間。

幾個(gè)常見(jiàn)的面試題

? AOF重寫(xiě)會(huì)阻塞主進(jìn)程嗎? 由上述AOF重寫(xiě)流程中,主進(jìn)程執(zhí)行AOF重寫(xiě)命令時(shí),類(lèi)似RDB的BGSAVE命令,也會(huì)fork出來(lái)一個(gè)子進(jìn)程用于AOF的重寫(xiě),此時(shí)并不會(huì)阻塞主進(jìn)程的讀寫(xiě)操作。當(dāng)然,在fork子進(jìn)程時(shí)會(huì)阻塞。

? 當(dāng)AOF重寫(xiě)時(shí),此時(shí)的寫(xiě)操作的數(shù)據(jù)會(huì)不會(huì)丟失? 由AOF重寫(xiě)流程,在子進(jìn)程執(zhí)行重寫(xiě)AOF時(shí),如果此時(shí)有數(shù)據(jù)寫(xiě)操作,此時(shí)仍然由主進(jìn)程完成,同時(shí)主進(jìn)程再把數(shù)據(jù)寫(xiě)入內(nèi)存后,會(huì)把命令寫(xiě)到一個(gè)內(nèi)存緩沖區(qū),也就是AOF重寫(xiě)緩沖區(qū),在子進(jìn)程完成AOF重寫(xiě),替換舊的AOF文件,生成新的AOF文件之后,會(huì)通知主進(jìn)程,此時(shí)主進(jìn)程會(huì)講重寫(xiě)緩沖區(qū)的命令追加到新的AOF文件之后。這樣就保證數(shù)據(jù)的完整性。

? 為什么AOF重寫(xiě)不復(fù)用原AOF日志? AOF重寫(xiě)不直接復(fù)用原AOF日志的原因主要是為了確保數(shù)據(jù)的一致性和提高重寫(xiě)效率。AOF重寫(xiě)的目的在于生成一個(gè)盡可能小的新AOF文件,該文件僅包含重建當(dāng)前數(shù)據(jù)集狀態(tài)所需的最少命令集。直接編輯原AOF文件難以直接去除冗余命令(比如某條數(shù)據(jù)可能有數(shù)次的變更后產(chǎn)生,其以前的命令就意義不大了)。從AOF重寫(xiě)流程上看,Redis會(huì)遍歷內(nèi)存數(shù)據(jù),將可以實(shí)現(xiàn)數(shù)據(jù)的最簡(jiǎn)潔的命令寫(xiě)入到臨時(shí)的AOF文件。

Redis在執(zhí)行AOF重寫(xiě)時(shí),主進(jìn)程仍繼續(xù)處理客戶(hù)端命令。如果直接修改原AOF文件,就需要復(fù)雜的并發(fā)控制來(lái)防止數(shù)據(jù)混亂,而使用新文件重寫(xiě)可以避免這種復(fù)雜性。通過(guò)子進(jìn)程執(zhí)行重寫(xiě),與主進(jìn)程的命令處理互不影響。

如果在嘗試修改原AOF文件的過(guò)程中遇到錯(cuò)誤或系統(tǒng)崩潰,可能會(huì)導(dǎo)致AOF文件損壞,進(jìn)而影響數(shù)據(jù)恢復(fù)。使用獨(dú)立的新文件進(jìn)行重寫(xiě),即便過(guò)程中出現(xiàn)問(wèn)題,原AOF文件依然可用。

并且,原AOF文件可能非常大,直接在原文件上進(jìn)行編輯操作可能會(huì)非常緩慢,影響Redis的服務(wù)性能。另外,文件系統(tǒng)的直接編輯操作通常比順序?qū)懭胄挛募臅r(shí),尤其是在有大量隨機(jī)讀寫(xiě)的情況下。

RDB與AOF的混合使用

為了同時(shí)獲得RDB的快速恢復(fù)速度和AOF的高度數(shù)據(jù)完整性,Redis支持將這兩種持久化策略結(jié)合起來(lái)使用?;旌鲜褂肦DB和AOF,取其二者的優(yōu)點(diǎn),可以實(shí)現(xiàn)數(shù)據(jù)安全性和恢復(fù)效率的最佳平衡。

在混合持久化模式下,Redis首先利用RDB文件快速恢復(fù)到某個(gè)時(shí)間點(diǎn)的數(shù)據(jù)庫(kù)狀態(tài),然后通過(guò)重放AOF日志來(lái)補(bǔ)充RDB快照之后的數(shù)據(jù)變更。RDB作為基礎(chǔ)恢復(fù),RDB快照提供了某一時(shí)間點(diǎn)的全量數(shù)據(jù)視圖,重啟時(shí)可以迅速加載到內(nèi)存,快速使服務(wù)可用。而AOF補(bǔ)充細(xì)節(jié),AOF日志用于填補(bǔ)從RDB快照以來(lái)的數(shù)據(jù)變動(dòng),使得Redis能夠逐步恢復(fù)到崩潰或重啟前的最新?tīng)顟B(tài)。

比如,針對(duì)RDB快照設(shè)置生成間隔的示例,我們使用AOF記錄寫(xiě)命令,當(dāng)某一時(shí)刻宕機(jī)后,恢復(fù)數(shù)據(jù)時(shí),我們可以從AOF中恢復(fù)上一次備份到這次宕機(jī)時(shí)保存的寫(xiě)操作對(duì)應(yīng)的數(shù)據(jù),當(dāng)數(shù)據(jù)恢復(fù)之后,再使用RDB進(jìn)行生成快照,然后再清空AOF文件。

圖片圖片

Redis重啟時(shí)判斷是否開(kāi)啟aof,如果開(kāi)啟了aof,那么就優(yōu)先加載aof文件;

這種方式的優(yōu)勢(shì)在于:結(jié)合RDB的快速加載能力和AOF的細(xì)粒度恢復(fù),達(dá)到了數(shù)據(jù)安全性和服務(wù)恢復(fù)速度的雙重優(yōu)化。根據(jù)業(yè)務(wù)對(duì)數(shù)據(jù)安全等級(jí)和恢復(fù)時(shí)間的要求,可以靈活調(diào)整RDB與AOF的比重和策略。通過(guò)合理配置RDB保存頻率和AOF重寫(xiě)策略,可以有效管理磁盤(pán)空間使用,避免不必要的資源浪費(fèi)。

生產(chǎn)環(huán)境的建議

在生產(chǎn)環(huán)境進(jìn)行Redis持久化時(shí),我們可以從以下幾個(gè)方面考慮:

1. 如果存儲(chǔ)在Redis中的數(shù)據(jù)相對(duì)不敏感或能便捷地重新生成,可以選擇暫時(shí)關(guān)閉持久化功能,以減少資源消耗。這樣即使偶發(fā)數(shù)據(jù)丟失,也能通過(guò)其他機(jī)制迅速恢復(fù)數(shù)據(jù)。比如一些數(shù)據(jù)相對(duì)于DB來(lái)說(shuō),并沒(méi)有經(jīng)過(guò)一些特殊處理,可以直接從DB中進(jìn)行恢復(fù),相當(dāng)于直接在DB做備份。

2. 在同一臺(tái)服務(wù)器部署多Redis實(shí)例時(shí),要注意協(xié)調(diào)各實(shí)例的持久化操作(如RDB快照或AOF重寫(xiě)),避免它們同時(shí)進(jìn)行,以免引發(fā)內(nèi)存、CPU或I/O資源的競(jìng)爭(zhēng),推薦采取串行執(zhí)行的方式,確保系統(tǒng)穩(wěn)定運(yùn)行。

3. 如果配置了Redis的主從,我們可以指定一個(gè)或多個(gè)從節(jié)點(diǎn)專(zhuān)門(mén)負(fù)責(zé)數(shù)據(jù)備份處理,這樣主節(jié)點(diǎn)就能專(zhuān)注于處理客戶(hù)端請(qǐng)求,提高整體服務(wù)的響應(yīng)速度和可用性。

4. 結(jié)合使用RDB和AOF兩種持久化方式,可以實(shí)現(xiàn)數(shù)據(jù)恢復(fù)的速度與完整性之間的一種最佳平衡。RDB提供快速恢復(fù)的能力,而AOF則能更詳盡地記錄每一步操作,兩者互補(bǔ),確保數(shù)據(jù)完整性。

責(zé)任編輯:武曉燕 來(lái)源: 碼農(nóng)Academy
相關(guān)推薦

2019-10-22 10:48:48

Redis集群架構(gòu)

2022-09-13 14:42:35

Redis內(nèi)存函數(shù)

2023-09-26 10:17:35

樓宇自動(dòng)化傳感器

2010-07-13 17:02:18

SQL Server

2025-05-06 07:45:12

2023-05-26 00:00:00

Redis持久化方式

2025-05-09 10:00:00

Vue開(kāi)發(fā)調(diào)試

2023-03-06 08:41:32

CPU使用率排查

2020-05-13 17:12:21

大數(shù)據(jù)分布式引擎

2017-10-23 13:20:37

2024-05-27 09:07:27

2023-03-27 15:37:43

自動(dòng)化測(cè)試開(kāi)發(fā)

2023-10-08 08:46:29

Java遍歷方式

2013-09-23 09:10:14

2019-11-18 16:20:48

RedisRDB數(shù)據(jù)庫(kù)

2024-12-27 09:21:58

2024-05-21 09:08:57

JVM調(diào)優(yōu)面試

2021-12-16 23:40:33

部署ReactTypeScript

2022-07-26 11:17:38

京東 APP新圖標(biāo)品牌升級(jí)

2010-04-19 17:27:53

無(wú)線上網(wǎng)貓
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)