本篇內(nèi)容介紹了“怎么掌握redis持久化RDB和AOF”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
東方ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
Redis對數(shù)據(jù)的操作都是基于內(nèi)存的,當(dāng)遇到了進(jìn)程退出、服務(wù)器宕機(jī)等意外情況,如果沒有持久化機(jī)制,那么Redis中的數(shù)據(jù)將會丟失無法恢復(fù)。有了持久化機(jī)制,Redis在下次重啟時(shí)可以利用之前持久化的文件進(jìn)行數(shù)據(jù)恢復(fù)。Redis支持的兩種持久化機(jī)制:
RDB:把當(dāng)前數(shù)據(jù)生成快照保存在硬盤上。
AOF:記錄每次對數(shù)據(jù)的操作到硬盤上。
在指定的時(shí)間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤,它恢復(fù)時(shí)是將快照文件直接讀到內(nèi)存里。RDB(Redis DataBase)持久化是把當(dāng)前Redis中全部數(shù)據(jù)生成快照保存在硬盤上。RDB持久化可以手動觸發(fā),也可以自動觸發(fā)。
redis會單獨(dú)創(chuàng)建(fork)一個(gè)子進(jìn)程來進(jìn)行持久化,會先將數(shù)據(jù)寫入到臨時(shí)文件中,待持久化過程都結(jié)束了,再用這個(gè)臨時(shí)文件替換上次持久化好了的文件。整個(gè)過程中,主進(jìn)程是不進(jìn)行任何IO操作的,這就確保了極高的性能。如果需要進(jìn)行大規(guī)模數(shù)據(jù)的恢復(fù),且對數(shù)據(jù)的恢復(fù)完整性不是非常敏感,那么RDB方式要比AOF方式更加的高效。RDB的缺點(diǎn)是最后一次持久化的數(shù)據(jù)可能丟失。
save
和 bgsave
命令都可以手動觸發(fā)RDB持久化。
save
執(zhí)行save
命令會手動觸發(fā)RDB持久化,但是save
命令會阻塞Redis服務(wù),直到RDB持久化完成。當(dāng)Redis服務(wù)儲存大量數(shù)據(jù)時(shí),會造成較長時(shí)間的阻塞,不建議使用。
bgsave
執(zhí)行bgsave
命令也會手動觸發(fā)RDB持久化,和save
命令不同是:Redis服務(wù)一般不會阻塞。Redis進(jìn)程會執(zhí)行fork操作創(chuàng)建子進(jìn)程,RDB持久化由子進(jìn)程負(fù)責(zé),不會阻塞Redis服務(wù)進(jìn)程。Redis服務(wù)的阻塞只發(fā)生在fork階段,一般情況時(shí)間很短。bgsave
命令的具體流程如下圖:
1、執(zhí)行bgsave
命令,Redis進(jìn)程先判斷當(dāng)前是否存在正在執(zhí)行的RDB或AOF子線程,如果存在就是直接結(jié)束。
2、Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子線程,在fork操作的過程中Redis進(jìn)程會被阻塞。
3、Redis進(jìn)程fork完成后,bgsave
命令就結(jié)束了,自此Redis進(jìn)程不會被阻塞,可以響應(yīng)其他命令。
4、子進(jìn)程根據(jù)Redis進(jìn)程的內(nèi)存生成快照文件,并替換原有的RDB文件。
5、同時(shí)發(fā)送信號給主進(jìn)程,通知主進(jìn)程rdb持久化完成,主進(jìn)程更新相關(guān)的統(tǒng)計(jì)信息(info Persitence下的rdb_*相關(guān)選項(xiàng))。
除了執(zhí)行以上命令手動觸發(fā)以外,Redis內(nèi)部可以自動觸發(fā)RDB持久化。自動觸發(fā)的RDB持久化都是采用bgsave
的方式,減少Redis進(jìn)程的阻塞。那么,在什么場景下會自動觸發(fā)呢?
在配置文件中設(shè)置了save
的相關(guān)配置,如sava m n
,它表示在m秒內(nèi)數(shù)據(jù)被修改過n次時(shí),自動觸發(fā)bgsave
操作。
當(dāng)從節(jié)點(diǎn)做全量復(fù)制時(shí),主節(jié)點(diǎn)會自動執(zhí)行bgsave
操作,并且把生成的RDB文件發(fā)送給從節(jié)點(diǎn)。
執(zhí)行debug reload
命令時(shí),也會自動觸發(fā)bgsave
操作。
執(zhí)行shutdown
命令時(shí),如果沒有開啟AOF持久化也會自動觸發(fā)bgsave
操作。
RDB文件是一個(gè)緊湊的二進(jìn)制壓縮文件,是Redis在某個(gè)時(shí)間點(diǎn)的全部數(shù)據(jù)快照。所以使用RDB恢復(fù)數(shù)據(jù)的速度遠(yuǎn)遠(yuǎn)比AOF的快,非常適合備份、全量復(fù)制、災(zāi)難恢復(fù)等場景。
每次進(jìn)行bgsave
操作都要執(zhí)行fork操作創(chuàng)建子經(jīng)常,屬于重量級操作,頻繁執(zhí)行成本過高,所以無法做到實(shí)時(shí)持久化,或者秒級持久化。
另外,由于Redis版本的不斷迭代,存在不同格式的RDB版本,有可能出現(xiàn)低版本的RDB格式無法兼容高版本RDB文件的問題。
快照周期:內(nèi)存快照雖然可以通過技術(shù)人員手動執(zhí)行SAVE
或BGSAVE
命令來進(jìn)行,但生產(chǎn)環(huán)境下多數(shù)情況都會設(shè)置其周期性執(zhí)行條件。
Redis中默認(rèn)的周期新設(shè)置
# 周期性執(zhí)行條件的設(shè)置格式為 save <seconds> <changes> # 默認(rèn)的設(shè)置為: save 900 1 save 300 10 save 60 10000 # 以下設(shè)置方式為關(guān)閉RDB快照功能 save ""
以上三項(xiàng)默認(rèn)信息設(shè)置代表的意義是:
如果900秒內(nèi)有1條Key信息發(fā)生變化,則進(jìn)行快照;
如果300秒內(nèi)有10條Key信息發(fā)生變化,則進(jìn)行快照;
如果60秒內(nèi)有10000條Key信息發(fā)生變化,則進(jìn)行快照。讀者可以按照這個(gè)規(guī)則,根據(jù)自己的實(shí)際請求壓力進(jìn)行設(shè)置調(diào)整。
其它相關(guān)配置
# 文件名稱 dbfilename dump.rdb # 文件保存路徑 dir ./ # 如果持久化出錯,主進(jìn)程是否停止寫入 stop-writes-on-bgsave-error yes # 是否壓縮 rdbcompression yes # 導(dǎo)入時(shí)是否檢查 rdbchecksum yes
dbfilename:RDB文件在磁盤上的名稱。
dir:RDB文件的存儲路徑。默認(rèn)設(shè)置為“./”,也就是Redis服務(wù)的主目錄。
stop-writes-on-bgsave-error:上文提到的在快照進(jìn)行過程中,主進(jìn)程照樣可以接受客戶端的任何寫操作的特性,是指在快照操作正常的情況下。如果快照操作出現(xiàn)異常(例如操作系統(tǒng)用戶權(quán)限不夠、磁盤空間寫滿等等)時(shí),Redis就會禁止寫操作。這個(gè)特性的主要目的是使運(yùn)維人員在第一時(shí)間就發(fā)現(xiàn)Redis的運(yùn)行錯誤,并進(jìn)行解決。一些特定的場景下,您可能需要對這個(gè)特性進(jìn)行配置,這時(shí)就可以調(diào)整這個(gè)參數(shù)項(xiàng)。該參數(shù)項(xiàng)默認(rèn)情況下值為yes,如果要關(guān)閉這個(gè)特性,指定即使出現(xiàn)快照錯誤Redis一樣允許寫操作,則可以將該值更改為no。
rdbcompression:該屬性將在字符串類型的數(shù)據(jù)被快照到磁盤文件時(shí),啟用LZF壓縮算法。Redis官方的建議是請保持該選項(xiàng)設(shè)置為yes,因?yàn)椤癷t’s almost always a win”。
rdbchecksum:從RDB快照功能的version 5 版本開始,一個(gè)64位的CRC冗余校驗(yàn)編碼會被放置在RDB文件的末尾,以便對整個(gè)RDB文件的完整性進(jìn)行驗(yàn)證。這個(gè)功能大概會多損失10%左右的性能,但獲得了更高的數(shù)據(jù)可靠性。所以如果您的Redis服務(wù)需要追求極致的性能,就可以將這個(gè)選項(xiàng)設(shè)置為no。
由于生產(chǎn)環(huán)境中我們?yōu)镽edis開辟的內(nèi)存區(qū)域都比較大(例如6GB),那么將內(nèi)存中的數(shù)據(jù)同步到硬盤的過程可能就會持續(xù)比較長的時(shí)間,而實(shí)際情況是這段時(shí)間Redis服務(wù)一般都會收到數(shù)據(jù)寫操作請求。那么如何保證數(shù)據(jù)一致性呢?
RDB中的核心思路是Copy-on-Write,來保證在進(jìn)行快照操作的這段時(shí)間,需要壓縮寫入磁盤上的數(shù)據(jù)在內(nèi)存中不會發(fā)生變化。在正常的快照操作中,一方面Redis主進(jìn)程會fork一個(gè)新的快照進(jìn)程專門來做這個(gè)事情,這樣保證了Redis服務(wù)不會停止對客戶端包括寫請求在內(nèi)的任何響應(yīng)。另一方面這段時(shí)間發(fā)生的數(shù)據(jù)變化會以副本的方式存放在另一個(gè)新的內(nèi)存區(qū)域,待快照操作結(jié)束后才會同步到原來的內(nèi)存區(qū)域。
舉個(gè)例子:如果主線程對這些數(shù)據(jù)也都是讀操作(例如圖中的鍵值對 A),那么,主線程和 bgsave
子進(jìn)程相互不影響。但是,如果主線程要修改一塊數(shù)據(jù)(例如圖中的鍵值對 C),那么,這塊數(shù)據(jù)就會被復(fù)制一份,生成該數(shù)據(jù)的副本。然后,bgsave
子進(jìn)程會把這個(gè)副本數(shù)據(jù)寫入 RDB 文件,而在這個(gè)過程中,主線程仍然可以直接修改原來的數(shù)據(jù)。
在進(jìn)行快照操作的這段時(shí)間,如果發(fā)生服務(wù)崩潰怎么辦?
很簡單,在沒有將數(shù)據(jù)全部寫入到磁盤前,這次快照操作都不算成功。如果出現(xiàn)了服務(wù)崩潰的情況,將以上一次完整的RDB快照文件作為恢復(fù)內(nèi)存數(shù)據(jù)的參考。也就是說,在快照操作過程中不能影響上一次的備份數(shù)據(jù)。Redis服務(wù)會在磁盤上創(chuàng)建一個(gè)臨時(shí)文件進(jìn)行數(shù)據(jù)操作,待操作成功后才會用這個(gè)臨時(shí)文件替換掉上一次的備份。
可以每秒做一次快照嗎?
對于快照來說,所謂“連拍”就是指連續(xù)地做快照。這樣一來,快照的間隔時(shí)間變得很短,即使某一時(shí)刻發(fā)生宕機(jī)了,因?yàn)樯弦粫r(shí)刻快照剛執(zhí)行,丟失的數(shù)據(jù)也不會太多。但是,這其中的快照間隔時(shí)間就很關(guān)鍵了。
如下圖所示,我們先在 T0 時(shí)刻做了一次快照,然后又在 T0+t 時(shí)刻做了一次快照,在這期間,數(shù)據(jù)塊 5 和 9 被修改了。如果在 t 這段時(shí)間內(nèi),機(jī)器宕機(jī)了,那么,只能按照 T0 時(shí)刻的快照進(jìn)行恢復(fù)。此時(shí),數(shù)據(jù)塊 5 和 9 的修改值因?yàn)闆]有快照記錄,就無法恢復(fù)了。
針對RDB不適合實(shí)時(shí)持久化的問題,Redis提供了AOF持久化方式來解決
AOF(Append Only File)持久化是把每次寫命令追加寫入日志中,當(dāng)需要恢復(fù)數(shù)據(jù)時(shí)重新執(zhí)行AOF文件中的命令就可以了。AOF解決了數(shù)據(jù)持久化的實(shí)時(shí)性,也是目前主流的Redis持久化方式。
Redis是“寫后”日志,Redis先執(zhí)行命令,把數(shù)據(jù)寫入內(nèi)存,然后才記錄日志。日志里記錄的是Redis收到的每一條命令,這些命令是以文本形式保存。PS: 大多數(shù)的數(shù)據(jù)庫采用的是寫前日志(WAL),例如MySQL,通過寫前日志和兩階段提交,實(shí)現(xiàn)數(shù)據(jù)和邏輯的一致性。
而AOF日志采用寫后日志,即先寫內(nèi)存,后寫日志。
為什么采用寫后日志?
Redis要求高性能,采用寫日志有兩方面好處:
避免額外的檢查開銷:Redis 在向 AOF 里面記錄日志的時(shí)候,并不會先去對這些命令進(jìn)行語法檢查。所以,如果先記日志再執(zhí)行命令的話,日志中就有可能記錄了錯誤的命令,Redis 在使用日志恢復(fù)數(shù)據(jù)時(shí),就可能會出錯。
不會阻塞當(dāng)前的寫操作
但這種方式存在潛在風(fēng)險(xiǎn):
如果命令執(zhí)行完成,寫日志之前宕機(jī)了,會丟失數(shù)據(jù)。
主線程寫磁盤壓力大,導(dǎo)致寫盤慢,阻塞后續(xù)操作。
AOF日志記錄Redis的每個(gè)寫命令,步驟分為:命令追加(append)、文件寫入(write)和文件同步(sync)。
命令追加當(dāng)AOF持久化功能打開了,服務(wù)器在執(zhí)行完一個(gè)寫命令之后,會以協(xié)議格式將被執(zhí)行的寫命令追加到服務(wù)器的 aof_buf 緩沖區(qū)。
文件寫入和同步關(guān)于何時(shí)將 aof_buf 緩沖區(qū)的內(nèi)容寫入AOF文件中,Redis提供了三種寫回策略:
Always,同步寫回:每個(gè)寫命令執(zhí)行完,立馬同步地將日志寫回磁盤;
Everysec,每秒寫回:每個(gè)寫命令執(zhí)行完,只是先把日志寫到AOF文件的內(nèi)存緩沖區(qū),每隔一秒把緩沖區(qū)中的內(nèi)容寫入磁盤;
No,操作系統(tǒng)控制的寫回:每個(gè)寫命令執(zhí)行完,只是先把日志寫到AOF文件的內(nèi)存緩沖區(qū),由操作系統(tǒng)決定何時(shí)將緩沖區(qū)內(nèi)容寫回磁盤。
默認(rèn)情況下,Redis是沒有開啟AOF的,可以通過配置redis.conf文件來開啟AOF持久化,關(guān)于AOF的配置如下:
# appendonly參數(shù)開啟AOF持久化 appendonly no # AOF持久化的文件名,默認(rèn)是appendonly.aof appendfilename "appendonly.aof" # AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數(shù)設(shè)置的 dir ./ # 同步策略 # appendfsync always appendfsync everysec # appendfsync no # aof重寫期間是否同步 no-appendfsync-on-rewrite no # 重寫觸發(fā)配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 加載aof出錯如何處理 aof-load-truncated yes # 文件重寫策略 aof-rewrite-incremental-fsync yes
以下是Redis中關(guān)于AOF的主要配置信息:
appendfsync:這個(gè)參數(shù)項(xiàng)是AOF功能最重要的設(shè)置項(xiàng)之一,主要用于設(shè)置“真正執(zhí)行”操作命令向AOF文件中同步的策略。
什么叫“真正執(zhí)行”呢?還記得Linux操作系統(tǒng)對磁盤設(shè)備的操作方式嗎? 為了保證操作系統(tǒng)中I/O隊(duì)列的操作效率,應(yīng)用程序提交的I/O操作請求一般是被放置在linux Page Cache中的,然后再由Linux操作系統(tǒng)中的策略自行決定正在寫到磁盤上的時(shí)機(jī)。而Redis中有一個(gè)fsync()函數(shù),可以將Page Cache中待寫的數(shù)據(jù)真正寫入到物理設(shè)備上,而缺點(diǎn)是頻繁調(diào)用這個(gè)fsync()函數(shù)干預(yù)操作系統(tǒng)的既定策略,可能導(dǎo)致I/O卡頓的現(xiàn)象頻繁 。
與上節(jié)對應(yīng),appendfsync參數(shù)項(xiàng)可以設(shè)置三個(gè)值,分別是:always、everysec、no,默認(rèn)的值為everysec。
no-appendfsync-on-rewrite:always和everysec的設(shè)置會使真正的I/O操作高頻度的出現(xiàn),甚至?xí)霈F(xiàn)長時(shí)間的卡頓情況,這個(gè)問題出現(xiàn)在操作系統(tǒng)層面上,所有靠工作在操作系統(tǒng)之上的Redis是沒法解決的。為了盡量緩解這個(gè)情況,Redis提供了這個(gè)設(shè)置項(xiàng),保證在完成fsync函數(shù)調(diào)用時(shí),不會將這段時(shí)間內(nèi)發(fā)生的命令操作放入操作系統(tǒng)的Page Cache(這段時(shí)間Redis還在接受客戶端的各種寫操作命令)。
auto-aof-rewrite-percentage:上文說到在生產(chǎn)環(huán)境下,技術(shù)人員不可能隨時(shí)隨地使用“BGREWRITEAOF
”命令去重寫AOF文件。所以更多時(shí)候我們需要依靠Redis中對AOF文件的自動重寫策略。Redis中對觸發(fā)自動重寫AOF文件的操作提供了兩個(gè)設(shè)置:
auto-aof-rewrite-percentage表示如果當(dāng)前AOF文件的大小超過了上次重寫后AOF文件的百分之多少后,就再次開始重寫AOF文件。例如該參數(shù)值的默認(rèn)設(shè)置值為100,意思就是如果AOF文件的大小超過上次AOF文件重寫后的1倍,就啟動重寫操作。
auto-aof-rewrite-min-size:設(shè)置項(xiàng)表示啟動AOF文件重寫操作的AOF文件最小大小。如果AOF文件大小低于這個(gè)值,則不會觸發(fā)重寫操作。注意,auto-aof-rewrite-percentage和auto-aof-rewrite-min-size只是用來控制Redis中自動對AOF文件進(jìn)行重寫的情況,如果是技術(shù)人員手動調(diào)用“BGREWRITEAOF
”命令,則不受這兩個(gè)限制條件左右。
AOF會記錄每個(gè)寫命令到AOF文件,隨著時(shí)間越來越長,AOF文件會變得越來越大。如果不加以控制,會對Redis服務(wù)器,甚至對操作系統(tǒng)造成影響,而且AOF文件越大,數(shù)據(jù)恢復(fù)也越慢。為了解決AOF文件體積膨脹的問題,Redis提供AOF文件重寫機(jī)制來對AOF文件進(jìn)行“瘦身”。
圖例解釋AOF重寫
AOF重寫會阻塞嗎?
AOF重寫過程是由后臺進(jìn)程bgrewriteaof來完成的。主線程fork出后臺的bgrewriteaof子進(jìn)程,fork會把主線程的內(nèi)存拷貝一份給bgrewriteaof子進(jìn)程,這里面就包含了數(shù)據(jù)庫的最新數(shù)據(jù)。然后,bgrewriteaof子進(jìn)程就可以在不影響主線程的情況下,逐一把拷貝的數(shù)據(jù)寫成操作,記入重寫日志。所以aof在重寫時(shí),在fork進(jìn)程時(shí)是會阻塞住主線程的。
AOF日志何時(shí)會重寫?
有兩個(gè)配置項(xiàng)控制AOF重寫的觸發(fā):
auto-aof-rewrite-min-size:表示運(yùn)行AOF重寫時(shí)文件的最小大小,默認(rèn)為64MB。
auto-aof-rewrite-percentage:這個(gè)值的計(jì)算方式是,當(dāng)前aof文件大小和上一次重寫后aof文件大小的差值,再除以上一次重寫后aof文件大小。也就是當(dāng)前aof文件比上一次重寫后aof文件的增量大小,和上一次重寫后aof文件大小的比值。
重寫日志時(shí),有新數(shù)據(jù)寫入咋整?
重寫過程總結(jié)為:“一個(gè)拷貝,兩處日志”。在fork出子進(jìn)程時(shí)的拷貝,以及在重寫時(shí),如果有新數(shù)據(jù)寫入,主線程就會將命令記錄到兩個(gè)aof日志內(nèi)存緩沖區(qū)中。如果AOF寫回策略配置的是always,則直接將命令寫回舊的日志文件,并且保存一份命令至AOF重寫緩沖區(qū),這些操作對新的日志文件是不存在影響的。(舊的日志文件:主線程使用的日志文件,新的日志文件:bgrewriteaof進(jìn)程使用的日志文件)
而在bgrewriteaof子進(jìn)程完成日志文件的重寫操作后,會提示主線程已經(jīng)完成重寫操作,主線程會將AOF重寫緩沖中的命令追加到新的日志文件后面。這時(shí)候在高并發(fā)的情況下,AOF重寫緩沖區(qū)積累可能會很大,這樣就會造成阻塞,Redis后來通過Linux管道技術(shù)讓aof重寫期間就能同時(shí)進(jìn)行回放,這樣aof重寫結(jié)束后只需回放少量剩余的數(shù)據(jù)即可。最后通過修改文件名的方式,保證文件切換的原子性。
在AOF重寫日志期間發(fā)生宕機(jī)的話,因?yàn)槿罩疚募€沒切換,所以恢復(fù)數(shù)據(jù)時(shí),用的還是舊的日志文件。
總結(jié)操作:
主線程fork出子進(jìn)程重寫aof日志
子進(jìn)程重寫日志完成后,主線程追加aof日志緩沖
替換日志文件
溫馨提示
這里的進(jìn)程和線程的概念有點(diǎn)混亂。因?yàn)楹笈_的bgreweiteaof進(jìn)程就只有一個(gè)線程在操作,而主線程是Redis的操作進(jìn)程,也是單獨(dú)一個(gè)線程。這里想表達(dá)的是Redis主進(jìn)程在fork出一個(gè)后臺進(jìn)程之后,后臺進(jìn)程的操作和主進(jìn)程是沒有任何關(guān)聯(lián)的,也不會阻塞主線程
主線程fork出子進(jìn)程是如何復(fù)制內(nèi)存數(shù)據(jù)的?
fork采用操作系統(tǒng)提供的寫時(shí)復(fù)制(copy on write)機(jī)制,就是為了避免一次性拷貝大量內(nèi)存數(shù)據(jù)給子進(jìn)程造成阻塞。fork子進(jìn)程時(shí),子進(jìn)程時(shí)會拷貝父進(jìn)程的頁表,即虛實(shí)映射關(guān)系(虛擬內(nèi)存和物理內(nèi)存的映射索引表),而不會拷貝物理內(nèi)存。這個(gè)拷貝會消耗大量cpu資源,并且拷貝完成前會阻塞主線程,阻塞時(shí)間取決于內(nèi)存中的數(shù)據(jù)量,數(shù)據(jù)量越大,則內(nèi)存頁表越大??截愅瓿珊?,父子進(jìn)程使用相同的內(nèi)存地址空間。
但主進(jìn)程是可以有數(shù)據(jù)寫入的,這時(shí)候就會拷貝物理內(nèi)存中的數(shù)據(jù)。如下圖(進(jìn)程1看做是主進(jìn)程,進(jìn)程2看做是子進(jìn)程):
在主進(jìn)程有數(shù)據(jù)寫入時(shí),而這個(gè)數(shù)據(jù)剛好在頁c中,操作系統(tǒng)會創(chuàng)建這個(gè)頁面的副本(頁c的副本),即拷貝當(dāng)前頁的物理數(shù)據(jù),將其映射到主進(jìn)程中,而子進(jìn)程還是使用原來的的頁c。
在重寫日志整個(gè)過程時(shí),主線程有哪些地方會被阻塞?
fork子進(jìn)程時(shí),需要拷貝虛擬頁表,會對主線程阻塞。
主進(jìn)程有bigkey寫入時(shí),操作系統(tǒng)會創(chuàng)建頁面的副本,并拷貝原有的數(shù)據(jù),會對主線程阻塞。
子進(jìn)程重寫日志完成后,主進(jìn)程追加aof重寫緩沖區(qū)時(shí)可能會對主線程阻塞。
為什么AOF重寫不復(fù)用原AOF日志?
父子進(jìn)程寫同一個(gè)文件會產(chǎn)生競爭問題,影響父進(jìn)程的性能。
如果AOF重寫過程中失敗了,相當(dāng)于污染了原本的AOF文件,無法做恢復(fù)數(shù)據(jù)使用。
Redis 4.0 中提出了一個(gè)混合使用 AOF 日志和內(nèi)存快照的方法。簡單來說,內(nèi)存快照以一定的頻率執(zhí)行,在兩次快照之間,使用 AOF 日志記錄這期間的所有命令操作。
這樣一來,快照不用很頻繁地執(zhí)行,這就避免了頻繁 fork 對主線程的影響。而且,AOF 日志也只用記錄兩次快照間的操作,也就是說,不需要記錄所有操作了,因此,就不會出現(xiàn)文件過大的情況了,也可以避免重寫開銷。
如下圖所示,T1 和 T2 時(shí)刻的修改,用 AOF 日志記錄,等到第二次做全量快照時(shí),就可以清空 AOF 日志,因?yàn)榇藭r(shí)的修改都已經(jīng)記錄到快照中了,恢復(fù)時(shí)就不再用日志了。
這個(gè)方法既能享受到 RDB 文件快速恢復(fù)的好處,又能享受到 AOF 只記錄操作命令的簡單優(yōu)勢, 實(shí)際環(huán)境中用的很多。
數(shù)據(jù)的備份、持久化做完了,我們?nèi)绾螐倪@些持久化文件中恢復(fù)數(shù)據(jù)呢?如果一臺服務(wù)器上有既有RDB文件,又有AOF文件,該加載誰呢?
其實(shí)想要從這些文件中恢復(fù)數(shù)據(jù),只需要重新啟動Redis即可。我們還是通過圖來了解這個(gè)流程:
redis重啟時(shí)判斷是否開啟aof,如果開啟了aof,那么就優(yōu)先加載aof文件;
如果aof存在,那么就去加載aof文件,加載成功的話redis重啟成功,如果aof文件加載失敗,那么會打印日志表示啟動失敗,此時(shí)可以去修復(fù)aof文件后重新啟動;
若aof文件不存在,那么redis就會轉(zhuǎn)而去加載rdb文件,如果rdb文件不存在,redis直接啟動成功;
如果rdb文件存在就會去加載rdb文件恢復(fù)數(shù)據(jù),如加載失敗則打印日志提示啟動失敗,如加載成功,那么redis重啟成功,且使用rdb文件恢復(fù)數(shù)據(jù);
那么為什么會優(yōu)先加載AOF呢?因?yàn)锳OF保存的數(shù)據(jù)更完整,通過上面的分析我們知道AOF基本上最多損失1s的數(shù)據(jù)。
“怎么掌握Redis持久化RDB和AOF”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
文章題目:怎么掌握Redis持久化RDB和AOF
分享路徑:http://aaarwkj.com/article44/gihgee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站策劃、營銷型網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、定制開發(fā)、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)