redis提供了兩種持久化的機(jī)制 RDB和AOF機(jī)制
RDB(redis Database):RDB保存某一個(gè)時(shí)間點(diǎn)之前的快照數(shù)據(jù)。
AOF(Append-Only File):指所有的命令行記錄以redis命令請(qǐng)求協(xié)議的格式完全持久化存儲(chǔ)保存為aof文件
混合持久化(4.0版本以后):指進(jìn)行AOF重寫時(shí),子進(jìn)程將當(dāng)前時(shí)間點(diǎn)的數(shù)據(jù)快照保存為RDB文件格式,而后將父進(jìn)程累計(jì)命令保存為AOF格式。
RDB快照有兩種觸發(fā)方式
1:未通過配置參數(shù),如下:
通過一定的時(shí)間周期內(nèi)看,命令執(zhí)行的個(gè)數(shù),超過閾值立即執(zhí)行快照生成
save9001//900秒內(nèi)有1次更新save30010//30秒內(nèi)有10次更新save6010000//60秒內(nèi)有10000次更新
2:手動(dòng)執(zhí)行bgsave/save,手動(dòng)觸發(fā)生成快照 直接執(zhí)行save會(huì)阻塞主進(jìn)程,bgsave的話會(huì)fork一個(gè)子進(jìn)程完成快照
但是redis在發(fā)生RDB持久化的過程中有幾個(gè)問題需要思考
1.RDB快照過程中Redis是否會(huì)停止對(duì)外服務(wù) 2.如果不會(huì)停止服務(wù),那如何處理新的請(qǐng)求
接下來我們看redis的RDB持久化的具體過程

1:主進(jìn)程會(huì)fork一個(gè)子進(jìn)程
2:子進(jìn)程會(huì)共享一部分主進(jìn)程的數(shù)據(jù)空間,并且把共享的數(shù)據(jù)置為read-only的狀態(tài),在這個(gè)過程中,子進(jìn)程以rdb的協(xié)議來實(shí)行持久化
3:在持久化的過程中是避免不了有新的數(shù)據(jù)寫入的,因?yàn)槲覀冇幸徊糠值臄?shù)據(jù)是共享的,兩個(gè)進(jìn)程同時(shí)擁有一塊數(shù)據(jù),肯定會(huì)導(dǎo)致數(shù)據(jù)不一致的問題, 但是依賴于操作系統(tǒng)的fork機(jī)制,在修改的時(shí)候一定是修改部分內(nèi)存頁(yè)的數(shù)據(jù),這個(gè)時(shí)候會(huì)觸發(fā)對(duì)應(yīng)內(nèi)存頁(yè)的copyonwrite的操作,不會(huì)影響子進(jìn)程完 成持久化,持久化結(jié)束后,主進(jìn)程會(huì)對(duì)子進(jìn)程進(jìn)行回收
RDB的文件格式

redis的rdb文件是一個(gè)非常緊湊的格式
開頭的REDIS是固定的一個(gè)格式,redis在讀取持久化文件的時(shí)候發(fā)現(xiàn)不是以REDIS開頭的會(huì)報(bào)錯(cuò)
0006是RDB_VERSION當(dāng)前RDB協(xié)議的版本
AUX_FIELD_KEY_VALUE_PAIRS是一些輔助的字段
data則為保存的數(shù)據(jù),數(shù)據(jù)首先會(huì)選擇redis_db,db選擇之后就是鍵值對(duì)的數(shù)據(jù),對(duì)應(yīng)的鍵值對(duì)又會(huì)分為設(shè)置過過期時(shí)間和未設(shè)置過期時(shí)間的數(shù)據(jù)
RDB持久化的優(yōu)點(diǎn)
1:二進(jìn)制的數(shù)據(jù)非常緊湊,數(shù)據(jù)的恢復(fù)速度非???/p>
2:在持久化的過程中,性能最大化,fork子進(jìn)程來完成寫操作,讓主進(jìn)程繼續(xù)處理命令,使用單獨(dú)子進(jìn)程來進(jìn)行持久化,保證了redis的高性能
RDB持久化的缺點(diǎn)
1:數(shù)據(jù)安全性低,RDB是間隔一段時(shí)間進(jìn)行持久化,如果持久化之間redis發(fā)生了故障,會(huì)發(fā)生數(shù)據(jù)丟失
2:linux fork之后,kernel把父進(jìn)程中所有的內(nèi)存頁(yè)權(quán)限都設(shè)置readonly,然后子進(jìn)程的地址空間指向父進(jìn)程。當(dāng)父子進(jìn)程都只讀內(nèi)存時(shí),相安無事。當(dāng)其中某個(gè)進(jìn)程寫內(nèi)存時(shí),CPU硬件檢測(cè)到內(nèi)存頁(yè)是read-only的,于是觸發(fā)頁(yè)異常終端(page-fault),陷入kernal的一個(gè)中斷例程。中斷例程中,kernel的copyonwrite機(jī)制就會(huì)把觸發(fā)的異常頁(yè)復(fù)制一份,于是父子進(jìn)程各自持有獨(dú)立的一份。如果這個(gè)時(shí)候有大量的寫入操作,會(huì)產(chǎn)生大量的分頁(yè)錯(cuò)誤(頁(yè)異常中斷page-fault ),這樣就得耗費(fèi)不少性能在復(fù)制上。
AOF持久化執(zhí)行流程
通過appendonly yes開啟

Redis使用單線程響應(yīng)命令,如果每次AOF文件命令都追加到磁盤,會(huì)極大的影響處理性能,所以Redis先寫入aof緩沖區(qū),根據(jù)用戶配置的同步磁盤策略寫入aof文件中,可以通過appendfsync參數(shù)配置同步策略:含義如下
appendfsyncalways#表示每次更新操作后手動(dòng)調(diào)用fsync()將數(shù)據(jù)寫入到磁盤appendfsync everysec#表示每秒同步一次(折中方案,默認(rèn)值)appendfsyncno#表述等操作系統(tǒng)進(jìn)行數(shù)據(jù)緩存同步到磁盤(快速響應(yīng)客戶端,不對(duì)AOF做數(shù)據(jù)同步,同步文件由操作系統(tǒng)負(fù)責(zé),通常同步周期最長(zhǎng)30S)
AOF重寫機(jī)制 隨著命令的不斷寫入AOF,文件會(huì)越來越大,為了解決這個(gè)問題Redis引入了AOF重寫機(jī)制壓縮文件體積。AOF文件重寫是把Redis進(jìn)程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫命令同步到新AOF文件的過程,AOF重寫機(jī)制可以通過手動(dòng)觸發(fā)了自動(dòng)觸發(fā)
手動(dòng)觸發(fā):bgreweuteaof命令
自動(dòng)觸發(fā):
auto-aof-rewrite-percentage100#表示當(dāng)前AOF文件空間和上一次重寫后AOF文件空間的比值(100%)auto-aof-rewrite-min-size64mb#代表AOF重寫時(shí)文件最小體積
AOF的優(yōu)點(diǎn):數(shù)據(jù)安全,AOF持久化可以配置appendfsync屬性,有always,每進(jìn)行一次命令操作就記錄到aof文件中一次。
AOF的缺點(diǎn):數(shù)據(jù)集比較大的時(shí)候,比RDB啟動(dòng)效率低
混合持久化
可以通過aof-use-rdb-preamble yes開啟
加載時(shí),首先會(huì)識(shí)別AOF文件是否以REDIS字符串開頭,如果是,就按照RDB格式加載,加載完RDB后繼續(xù)按AOF格式加載剩余部分。 混合式持久化方案兼顧了RDB的速度,和AOF的安全性
?原文鏈接:https://www.toutiao.com/a6881889234005950980/?log_from=4620416088736_1640165001204