自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

就這?Redis持久化策略——AOF

開發(fā) 前端 Redis
今天為大家介紹Redis的另一種持久化策略——AOF。注意:AOF文件只會(huì)記錄Redis的寫操作命令,因?yàn)樽x命令對數(shù)據(jù)的恢復(fù)沒有任何意義

今天為大家介紹Redis的另一種持久化策略——AOF。

什么是AOF

男孩“一覺醒來”忘記了對女孩子的承諾,這時(shí)候女孩子把曾經(jīng)海誓山盟的錄音逐條播放給男孩子聽,幫助他“恢復(fù)記憶”。

“男孩一覺醒來”像極了Redis宕機(jī)重啟的樣子,而女孩子的錄音就是Redis的AOF日志。

AOF(Append Only File)以文本的形式(文本格式由Redis自定義,后文會(huì)講到),通過將所有對數(shù)據(jù)庫的寫入命令記錄到AOF文件中,達(dá)到記錄數(shù)據(jù)庫狀態(tài)的目的。

注意:AOF文件只會(huì)記錄Redis的寫操作命令,因?yàn)樽x命令對數(shù)據(jù)的恢復(fù)沒有任何意義。

Redis默認(rèn)并未開啟AOF功能,redis.conf配置文件中,關(guān)于AOF的相關(guān)配置如下: 

  1. # 是否開啟AOF功能(開啟:yes 關(guān)閉:no) 
  2. appendonly yes 
  3. # 生成的AOF文件名稱 
  4. appendfilename 6379.aof 
  5. # AOF寫回策略 
  6. appendfsync everysec 
  7. # 當(dāng)前AOF文件大小和最后一次重寫后的大小之間的比率>=指定的增長百分比則進(jìn)行重寫 
  8. # 如100代表當(dāng)前AOF文件大小是上次重寫的兩倍時(shí)候才重寫 
  9. auto-aof-rewrite-percentage 100 
  10. # AOF文件最小重寫大小,只有當(dāng)AOF文件大小大于該值時(shí)候才可能重寫,4.0默認(rèn)配置64mb。 
  11. auto-aof-rewrite-min-size 64mb 

AOF日志格式

下面我們通過一個(gè)例子,看一下AOF機(jī)制是如何保存我們的操作日志的,我們對Redis進(jìn)行如下操作。 

  1. 127.0.0.1:6379[3]> RPUSH list 1 2 3 4 5 
  2. (integer) 5 
  3. 127.0.0.1:6379[3]> LRANGE list 0 -1 
  4. 1) "1" 
  5. 2) "2" 
  6. 3) "3" 
  7. 4) "4" 
  8. 5) "5" 
  9. 127.0.0.1:6379[3]> RPOP list 
  10. "5" 
  11. 127.0.0.1:6379[3]> LPUSH list 0 
  12. (integer) 5 
  13. 127.0.0.1:6379[3]> KEYS * 
  14. 1) "list" 
  15. 127.0.0.1:6379[3]> LRANGE list 0 -1 
  16. 1) "0" 
  17. 2) "1" 
  18. 3) "2" 
  19. 4) "3" 
  20. 5) "4" 

Redis會(huì)將上述所有的寫指令保存到AOF文件中,如下所示: 

  1. RPUSH list 1 2 3 4 5 
  2. RPOP list 
  3. LPUSH list 0 

當(dāng)然,AOF文件不是直接以指令的格式進(jìn)行存儲(chǔ)的,我們以第一條指令RPUSH list 1 2 3 4 5為例,看一下AOF文件實(shí)際保存該條指令的格式。 

  1. *2 
  2. $6 
  3. SELECT 
  4. $1 
  5. *7 
  6. $5 
  7. RPUSH 
  8. $4 
  9. list 
  10. $1 
  11. $1 
  12. $1 
  13. $1 
  14. $1 

除了 SELECT命令是AOF程序自己加上去的之外, 其他命令都是之前我們在終端里執(zhí)行的命令。自動(dòng)添加這條指令是因?yàn)镽edis恢復(fù)數(shù)據(jù)的時(shí)候需要知道待恢復(fù)的數(shù)據(jù)屬于哪一個(gè)數(shù)據(jù)庫。

其中,*2表示當(dāng)前命令有2個(gè)部分,每部分都是由$+數(shù)字開頭,后面緊跟著具體的命令、鍵或值。數(shù)字表示這部分中的命令、鍵或值一共有多少字節(jié)。例如,$6 SELECT表示這部分有 6 個(gè)字節(jié),也就是SELECT命令。

AOF日志的生成過程

從我們發(fā)送寫指令開始到指令保存在AOF文件中,需要經(jīng)歷4步,分別為命令傳播、命令追加、文件寫入和文件同步。

命令傳播

命令傳播:Redis 將執(zhí)行完的命令、命令的參數(shù)、命令的參數(shù)個(gè)數(shù)等信息發(fā)送到 AOF程序中。

大家有沒有關(guān)注到其中的一個(gè)細(xì)節(jié),AOF日志寫入是在Redis成功執(zhí)行命令之后才進(jìn)行的,為什么要在執(zhí)行之后而不是之前呢?原因有兩點(diǎn):

首先試想一下,如果我們不小心輸錯(cuò)了Redis指令,然后Redis緊接著將該指令保存到了AOF文件中,等到Redis進(jìn)行數(shù)據(jù)恢復(fù)的時(shí)候就可能導(dǎo)致錯(cuò)誤。因此這種寫后日志的形式可以避免對指令進(jìn)行語法檢查,避免出現(xiàn)記錄錯(cuò)誤指令的情況。

其次,先執(zhí)行命令后保存日志,不會(huì)阻塞當(dāng)前的寫操作。

但是,AOF寫后日志也有兩個(gè)風(fēng)險(xiǎn)。

第一個(gè)風(fēng)險(xiǎn),假如Redis寫操作成功之后突然宕機(jī),此時(shí)AOF日志還未來得及寫入,則該條指令和相關(guān)參數(shù)就有丟失的風(fēng)險(xiǎn)。

第二個(gè)風(fēng)險(xiǎn),AOF雖然避免了對當(dāng)前操作的阻塞,但是有可能阻塞下一個(gè)操作。因?yàn)楸4鍭OF日志的部分工作也是由主線程完成的(下文有詳細(xì)介紹),Redis的內(nèi)存操作速度和文件寫入速度簡直是云泥之別,如果主線程在文件保存的過程中花費(fèi)太長的時(shí)間必然會(huì)阻塞后續(xù)的操作。

分析就會(huì)發(fā)現(xiàn),第一個(gè)風(fēng)險(xiǎn)與AOF寫回磁盤的時(shí)機(jī)有關(guān),寫回磁盤的頻率越高,發(fā)生數(shù)據(jù)丟失的可能性就越小。第二個(gè)風(fēng)險(xiǎn)和文件寫入方式以及時(shí)機(jī)有關(guān),如果Redis每次成功執(zhí)行指令之后都力圖將當(dāng)前指令同步到AOF文件,開銷必然很大。

因此Redis引入了緩沖區(qū)的概念,緩沖區(qū)對應(yīng)了文件的寫入方式(不求一步到位,允許循序漸進(jìn)地寫入),而何時(shí)將緩沖區(qū)的內(nèi)容徹底同步到文件就涉及到了AOF的同步策略(寫回磁盤的時(shí)機(jī))。

命令追加

在AOF開啟的情況下,Redis會(huì)將成功執(zhí)行的寫指令以上文我們講過的協(xié)議格式追加到Redis的aof_buf緩沖區(qū)。 

  1. struct redisServer { 
  2.  
  3.     // ... 
  4.  
  5.     // AOF緩沖區(qū) 
  6.     sds aof_buf; 
  7.  
  8.     // ... 
  9. }; 

aof_buf 緩沖區(qū)保存著所有等待寫入到AOF 文件的協(xié)議文本。

至此,將命令追加到緩存區(qū)的步驟完成。

文件寫入

文件的寫入和同步操作往往被放在一起介紹,這里之所以分開,是想向讀者強(qiáng)調(diào)文件的寫入和同步是兩步不同的操作。

為了提高文件的寫入效率,當(dāng)用戶調(diào)用write函數(shù)將數(shù)據(jù)寫入到文件時(shí),操作系統(tǒng)內(nèi)核會(huì)將數(shù)據(jù)首先保存在內(nèi)存緩沖區(qū)中,等到緩沖區(qū)的空間被填滿或者到達(dá)一定的時(shí)機(jī)之后,內(nèi)核會(huì)將數(shù)據(jù)同步到磁盤。

這種同步過于依賴于操作系統(tǒng)內(nèi)核,時(shí)機(jī)無法掌控。為此,操作系統(tǒng)提供了fsync和fdatasync兩個(gè)同步函數(shù),可以強(qiáng)制內(nèi)核立即將緩沖區(qū)內(nèi)的數(shù)據(jù)同步到磁盤。

Redis的主服務(wù)進(jìn)程本質(zhì)上是一個(gè)死循環(huán),循環(huán)中有負(fù)責(zé)接受客戶端的請求,并向客戶端發(fā)送回執(zhí)的邏輯,我們稱之為文件事件。

在AOF功能開啟的情況下,文件事件會(huì)將成功執(zhí)行之后的寫命令追加到aof_buf緩沖區(qū),在主服務(wù)進(jìn)程死循環(huán)的最后,會(huì)調(diào)用flushAppendOnlyFile函數(shù),該函數(shù)會(huì)將aof_buf中的數(shù)據(jù)寫入到內(nèi)核緩沖區(qū),然后判斷是否應(yīng)該進(jìn)行同步。偽代碼如下: 

  1. void eventLoop { 
  2.      
  3.     while(true){ 
  4.          
  5.         // ... 
  6.  
  7.         // 文件事件,接受命令請求,返回客戶端回執(zhí) 
  8.         // 根據(jù)aof功能是否開啟,決定是否將寫命令追加到aof_buf緩沖區(qū) 
  9.         handleFileEvents(); 
  10.  
  11.         // 將aof_buf數(shù)據(jù)寫入內(nèi)核緩沖區(qū) 
  12.         // 判斷是否需要將數(shù)據(jù)同步到磁盤 
  13.         flushAppendOnlyFile(); 
  14.          
  15.         // ... 
  16.  
  17.     } 
  18.     
  19. }; 

而是否進(jìn)行同步則是由Redis配置中的appendOnlyFile選項(xiàng)來決定的。

文件同步

redis.conf配置文件中appendOnlyFile的選項(xiàng)有三個(gè)值可選,對應(yīng)三種AOF同步策略,分別是:

  • No :同步時(shí)機(jī)由內(nèi)核決定。
  • Everysec :每一秒鐘同步一次。
  • Always :每執(zhí)行一個(gè)命令同步一次。

No

由操作系統(tǒng)內(nèi)核決定同步時(shí)機(jī),每個(gè)寫命令執(zhí)行完,只是先把日志寫入AOF文件的內(nèi)核緩沖區(qū),不立即進(jìn)行同步。在這種模式下, 同步只會(huì)在以下任意一種情況下被執(zhí)行:

  • Redis 被關(guān)閉
  • AOF功能被關(guān)閉
  • 系統(tǒng)的寫緩存被刷新(可能是緩存已經(jīng)被寫滿,或者定期保存操作被執(zhí)行)

這三種情況下的同步操作都會(huì)引起 Redis 主進(jìn)程阻塞。

Everysec

如果用戶未指定appendOnlyFile的值,則默認(rèn)值為Everysec。每秒同步,每個(gè)寫命令執(zhí)行完,只是先把日志寫到 AOF文件的內(nèi)核緩沖區(qū),理論上每隔1秒把緩沖區(qū)中的內(nèi)容同步到磁盤,且同步操作有單獨(dú)的子線程進(jìn)行,因此不會(huì)阻塞主進(jìn)程。

需要注意的是,我們用的是「理論上」這樣的措辭,實(shí)際運(yùn)行中該模式對fsync或fdatasync的調(diào)用并不是每秒一次,而是和調(diào)用flushAppendOnlyFile函數(shù)時(shí)Redis所處的狀態(tài)有關(guān)。

每當(dāng) flushAppendOnlyFile 函數(shù)被調(diào)用時(shí), 可能會(huì)出現(xiàn)以下四種情況:

  • 子線程正在執(zhí)行同步,并且這個(gè)同步的執(zhí)行時(shí)間未超過 2 秒,那么程序直接返回 ;這個(gè)同步已經(jīng)執(zhí)行超過 2 秒,那么程序執(zhí)行寫入操作 ,但不執(zhí)行新的同步操作 。但是,這時(shí)的寫入操作必須等待子線程先完成原本的同步操作 ,因此這里的寫入操作會(huì)比平時(shí)阻塞更長時(shí)間。
  • 子線程沒有在執(zhí)行同步 ,并且上次成功執(zhí)行同步距今不超過1秒,那么程序執(zhí)行寫入,但不執(zhí)行同步 ;上次成功執(zhí)行同步距今已經(jīng)超過1秒,那么程序執(zhí)行寫入和同步 。

可以用流程圖表示這四種情況:

在Everysec模式下

  • 如果在情況1下宕機(jī),那么我們最多損失小于2秒內(nèi)的所有數(shù)據(jù)。
  • 如果在情況2下宕機(jī),那么我們損失的數(shù)據(jù)可能會(huì)超過2秒。

因此AOF在Everysec模式下只會(huì)丟失 1 秒鐘數(shù)據(jù)的說法實(shí)際上并不準(zhǔn)確。

Always

每個(gè)寫命令執(zhí)行完,立刻同步地將日志寫回磁盤。此模式下同步操作是由 Redis 主進(jìn)程執(zhí)行的,所以在同步執(zhí)行期間,主進(jìn)程會(huì)被阻塞,不能接受命令請求。

AOF同步策略小結(jié)

對于三種 AOF 同步模式, 它們對Redis主進(jìn)程的阻塞情況如下:

  1. 不同步(No):寫入和同步都由主進(jìn)程執(zhí)行,兩個(gè)操作都會(huì)阻塞主進(jìn)程;
  2. 每一秒鐘同步一次(Everysec):寫入操作由主進(jìn)程執(zhí)行,阻塞主進(jìn)程。同步操作由子線程執(zhí)行,不直接阻塞主進(jìn)程,但同步操作完成的快慢會(huì)影響寫入操作的阻塞時(shí)長;
  3. 每執(zhí)行一個(gè)命令同步一次(Always):同模式 1 。

因?yàn)樽枞僮鲿?huì)讓 Redis 主進(jìn)程無法持續(xù)處理請求, 所以一般說來, 阻塞操作執(zhí)行得越少、完成得越快, Redis 的性能就越好。

No的同步操作只會(huì)在AOF關(guān)閉或Redis關(guān)閉時(shí)執(zhí)行, 或由操作系統(tǒng)內(nèi)核觸發(fā)。在一般情況下, 這種模式只需要為寫入阻塞,因此它的寫入性能要比后面兩種模式要高, 但是這種性能的提高是以降低安全性為代價(jià)的:在這種模式下,如果發(fā)生宕機(jī),那么丟失的數(shù)據(jù)量由操作系統(tǒng)內(nèi)核的緩存沖洗策略決定。

Everysec在性能方面要優(yōu)于Always , 并且在通常情況下,這種模式最多丟失不多于2秒的數(shù)據(jù), 所以它的安全性要高于No ,這是一種兼顧性能和安全性的保存方案。

Always的安全性是最高的,但性能也是最差的,因?yàn)镽edis必須阻塞直到命令信息被寫入并同步到磁盤之后才能繼續(xù)處理請求。

三種 AOF模式的特性可以總結(jié)為如下表格

AOF生成過程小結(jié)

最后總結(jié)一下AOF文件的生成過程。以下步驟都是在AOF開啟的前提下進(jìn)行的

  1. Redis成功執(zhí)行寫操作指令,然后將寫的指令按照自定義格式追加到aof_buf緩沖區(qū),這是第一個(gè)緩沖區(qū);
  2. Redis主進(jìn)程將aof_buf緩沖區(qū)的數(shù)據(jù)寫入到內(nèi)核緩沖區(qū),這是第二個(gè)緩沖區(qū);
  3. 根據(jù)AOF同步策略適時(shí)地將內(nèi)核緩沖區(qū)的數(shù)據(jù)同步到磁盤,過程結(jié)束。

AOF文件的載入和數(shù)據(jù)還原

AOF文件中包含了能夠重建數(shù)據(jù)庫的所有寫命令,因此將所有命令讀入并依次執(zhí)行即可還原Redis之前的數(shù)據(jù)狀態(tài)。

Redis 讀取AOF文件并還原數(shù)據(jù)庫的詳細(xì)步驟如下:

  1. 創(chuàng)建一個(gè)不帶網(wǎng)絡(luò)連接的偽客戶端(fake client),偽客戶端執(zhí)行命令的效果, 和帶網(wǎng)絡(luò)連接的客戶端執(zhí)行命令的效果完全相同;
  2. 讀取AOF所保存的文本,并根據(jù)內(nèi)容還原出命令、命令的參數(shù)以及命令的個(gè)數(shù);
  3. 根據(jù)指令、指令的參數(shù)等信息,使用偽客戶端執(zhí)行命令。
  4. 執(zhí)行 2 和 3 ,直到AOF文件中的所有命令執(zhí)行完畢。

注意:為了避免對數(shù)據(jù)的完整性產(chǎn)生影響, 在服務(wù)器載入數(shù)據(jù)的過程中, 只有和數(shù)據(jù)庫無關(guān)的發(fā)布訂閱功能可以正常使用, 其他命令一律返回錯(cuò)誤。

AOF重寫

AOF的作用是幫我們還原Redis的數(shù)據(jù)狀態(tài),其中包含了所有的寫操作,但是正常情況下客戶端會(huì)對同一個(gè)KEY進(jìn)行多次不同的寫操作,如下: 

  1. 127.0.0.1:6379[3]> SET name chanmufeng1 
  2. OK 
  3. 127.0.0.1:6379[3]> SET name chanmufeng2 
  4. OK 
  5. 127.0.0.1:6379[3]> SET name chanmufeng3 
  6. OK 
  7. 127.0.0.1:6379[3]> SET name chanmufeng4 
  8. OK 
  9. 127.0.0.1:6379[3]> SET name chanmufeng 
  10. OK 

例子中對name的數(shù)據(jù)進(jìn)行寫操作就進(jìn)行了5次,其實(shí)對我們而言僅需要最后一條指令而已,但是AOF會(huì)將這5條指令都記錄下來。更極端的情況是有些被頻繁操作的鍵, 對它們所調(diào)用的命令可能有成百上千、甚至上萬條, 如果這樣被頻繁操作的鍵有很多的話,AOF文件的體積就會(huì)急速膨脹。

  • 首先,AOF文件的體積受操作系統(tǒng)大小的限制,本身就不能無限增長;
  • 其次,體積過于龐大的AOF文件會(huì)影響指令的寫入速度,阻塞時(shí)間延長;
  • 最后AOF文件的體積越大,Redis數(shù)據(jù)恢復(fù)所需的時(shí)間也就越長。

為了解決AOF文件體積龐大的問題,Redis提供了rewrite的AOF重寫功能來精簡AOF文件體積。

AOF重寫的實(shí)現(xiàn)原理

雖然叫AOF「重寫」,但是新AOF文件的生成并非是在原AOF文件的基礎(chǔ)上進(jìn)行操作得到的,而是讀取Redis當(dāng)前的數(shù)據(jù)狀態(tài)來重新生成的。不難理解,后者的處理方式遠(yuǎn)比前者高效。

為了避免阻塞主線程,導(dǎo)致數(shù)據(jù)庫性能下降,和 AOF 日志由主進(jìn)程寫回不同,重寫過程是由子進(jìn)程執(zhí)行bgrewriteaof 來完成的。這樣處理的最大好處是:

  • 子進(jìn)程進(jìn)行 AOF重寫期間,主進(jìn)程可以繼續(xù)處理命令請求;
  • 子進(jìn)程帶有主進(jìn)程的數(shù)據(jù)副本,操作效率更高。

這里有兩個(gè)問題值得我們來思考一下。

1.為什么使用子進(jìn)程,而不是多線程來進(jìn)行AOF重寫呢?

如果是使用線程,線程之間會(huì)共享內(nèi)存,在修改共享內(nèi)存數(shù)據(jù)的時(shí)候,需要通過加鎖來保證數(shù)據(jù)的安全,這樣就會(huì)降低性能。

如果使用子進(jìn)程,操作系統(tǒng)會(huì)使用「寫時(shí)復(fù)制」的技術(shù):fork子進(jìn)程時(shí),子進(jìn)程會(huì)拷貝父進(jìn)程的頁表,即虛實(shí)映射關(guān)系,而不會(huì)拷貝物理內(nèi)存。子進(jìn)程復(fù)制了父進(jìn)程頁表,也能共享訪問父進(jìn)程的內(nèi)存數(shù)據(jù),達(dá)到共享內(nèi)存的效果。

不過這個(gè)共享的內(nèi)存只能以只讀的方式,當(dāng)父子進(jìn)程任意一方修改了該共享內(nèi)存,就會(huì)發(fā)生「寫時(shí)復(fù)制」,于是父子進(jìn)程就有了獨(dú)立的數(shù)據(jù)副本,就不用加鎖來保證數(shù)據(jù)安全。

這里我把在就這?Redis持久化策略——RDB畫過的一張圖拿過來幫助大家理解一下寫時(shí)復(fù)制。

因此,有兩個(gè)過程可能會(huì)導(dǎo)致主進(jìn)程阻塞:

  • fork子進(jìn)程的過程中,由于要復(fù)制父進(jìn)程的頁表等數(shù)據(jù),阻塞的時(shí)間跟頁表的大小有關(guān),頁表越大阻塞的時(shí)間也越長,不過通常而言該過程是非??斓?
  • fork完子進(jìn)程后,如果父子進(jìn)程任意一方修改了共享數(shù)據(jù),就會(huì)發(fā)生「寫時(shí)復(fù)制」,這期間會(huì)拷貝物理內(nèi)存,如果內(nèi)存越大,自然阻塞的時(shí)間也越長。

針對第二個(gè)過程,有一個(gè)小細(xì)節(jié)在這里提一下。寫時(shí)復(fù)制,復(fù)制的粒度為一個(gè)內(nèi)存頁。如果只是修改一個(gè)256B的數(shù)據(jù),父進(jìn)程需要讀原來的整個(gè)內(nèi)存頁,然后再映射到新的物理地址寫入。一讀一寫會(huì)造成讀寫放大。如果內(nèi)存頁越大(例如2MB的大頁),那么讀寫放大也就越嚴(yán)重,對Redis性能造成影響。因此使用Redis的AOF功能時(shí),需要注意頁表的大小不要設(shè)置的太大。

2.子進(jìn)程在進(jìn)行 AOF 重寫期間,主進(jìn)程還需要繼續(xù)處理命令,而新的命令可能對現(xiàn)有的數(shù)據(jù)進(jìn)行修改, 會(huì)讓當(dāng)前數(shù)據(jù)庫的數(shù)據(jù)和重寫后的 AOF 文件中的數(shù)據(jù)不一致,這該怎么辦?

為了解決這個(gè)問題,Redis引入了另一個(gè)緩沖區(qū)的概念(這也是本文中涉及到的第3個(gè)緩沖區(qū)的概念)——AOF重寫緩沖區(qū)。

換言之, 當(dāng)子進(jìn)程在執(zhí)行AOF重寫(bgrewriteaof)時(shí), 主進(jìn)程需要執(zhí)行以下三個(gè)工作:

  • 處理客戶端的命令請求;
  • 將寫命令追加到AOF緩沖區(qū)(aof_buf);
  • 將寫命令追加到AOF重寫緩沖區(qū)。

這樣一來可以保證:

  • 現(xiàn)有的 AOF功能會(huì)繼續(xù)執(zhí)行,即使在 AOF 重寫期間發(fā)生停機(jī),也不會(huì)有任何數(shù)據(jù)丟失;
  • 所有對數(shù)據(jù)庫進(jìn)行修改的命令都會(huì)被記錄到AOF重寫緩沖區(qū)中。

當(dāng)子進(jìn)程完成 AOF重寫之后, 它會(huì)向父進(jìn)程發(fā)送一個(gè)完成信號(hào), 父進(jìn)程在接到完成信號(hào)之后, 會(huì)調(diào)用一個(gè)信號(hào)處理函數(shù), 并完成以下工作:

  • 將 AOF重寫緩沖區(qū)中的內(nèi)容全部寫入到新AOF 文件中;
  • 對新的 AOF 文件進(jìn)行改名,覆蓋原有的 AOF 文件。注意,這是一個(gè)原子操作,改名過程中不接受客戶端指令。

當(dāng)步驟 1 執(zhí)行完畢之后, 現(xiàn)有 AOF 文件、新 AOF 文件和數(shù)據(jù)庫三者的狀態(tài)就完全一致了。

當(dāng)步驟 2 執(zhí)行完畢之后, 程序就完成了新舊兩個(gè) AOF 文件的交替。

這個(gè)信號(hào)處理函數(shù)執(zhí)行完畢之后, 主進(jìn)程就可以繼續(xù)像往常一樣接受命令請求了。 在整個(gè) AOF 后臺(tái)重寫過程中, 只有將AOF重寫緩沖區(qū)數(shù)據(jù)寫入新AOF文件和改名操作會(huì)造成主進(jìn)程阻塞, 其他時(shí)候, AOF 后臺(tái)重寫都不會(huì)對主進(jìn)程造成阻塞, 這將 AOF 重寫對性能造成的影響降到了最低。

AOF 后臺(tái)重寫的觸發(fā)條件

再看一下關(guān)于AOF的其他兩個(gè)配置: 

  1. auto-aof-rewrite-percentage 100  
  2. auto-aof-rewrite-min-size 64mb 

AOF 重寫可以由用戶通過調(diào)用 bgrewriteaof手動(dòng)觸發(fā)。

另外, 服務(wù)器在 AOF 功能開啟的情況下, 會(huì)維持以下三個(gè)變量:

  • 記錄當(dāng)前 AOF 文件大小的變量 aof_current_size ;
  • 記錄最后一次 AOF 重寫之后, AOF 文件大小的變量 aof_rewrite_base_size ;
  • 增長百分比變量 aof_rewrite_perc 。

每次當(dāng)Redis中的定時(shí)函數(shù) serverCron 執(zhí)行時(shí), 它都會(huì)檢查以下條件是否全部滿足, 如果是的話, 就會(huì)觸發(fā)自動(dòng)的 AOF 重寫:

  1. 沒有 bgsave 命令在進(jìn)行。
  2. 沒有 bgrewriteaof 在進(jìn)行。
  3. 當(dāng)前 AOF 文件大小大于 我們設(shè)置的auto-aof-rewrite-min-size。
  4. 當(dāng)前 AOF 文件大小和最后一次 AOF 重寫后的大小之間的比率大于等于指定的增長百分比auto-aof-rewrite-percentage。

默認(rèn)情況下, 增長百分比為 100% , 也即是說, 如果前面三個(gè)條件都已經(jīng)滿足, 并且當(dāng)前 AOF 文件大小比最后一次 AOF 重寫時(shí)的大小要大一倍的話, 那么觸發(fā)自動(dòng) AOF 重寫。

小結(jié)

經(jīng)過多番改稿,終于!給大家梳理完成Redis的AOF持久化方法,最后我們簡單總結(jié)一下。

AOF是將Redis的所有寫日志同步到磁盤的一種持久化方法,通過執(zhí)行AOF中記錄的所有指令可以達(dá)到恢復(fù)Redis原始數(shù)據(jù)狀態(tài)的目的。

對于指令的同步時(shí)機(jī),Redis提供了三種AOF同步策略,分別是No,Everysec,Always,三種策略對Redis性能的負(fù)面影響是由低到高的,在數(shù)據(jù)可靠性上也是由低到高的。

為了解決AOF日志太大的問題,Redis提供了AOF重寫的機(jī)制,利用「寫時(shí)復(fù)制」和「AOF重寫緩沖區(qū)」達(dá)到精簡AOF文件的目的。

 

責(zé)任編輯:未麗燕 來源: 今日頭條
相關(guān)推薦

2023-05-11 09:12:35

RedisRDB日志

2021-07-18 07:59:42

RedisRDBAOF

2024-03-26 00:03:08

Redis數(shù)據(jù)RDB

2024-12-20 12:15:06

RedisRDB持久化

2019-05-17 08:55:49

RedisRDBAOF

2024-09-12 08:49:53

2025-03-14 08:00:00

AOFRedis數(shù)據(jù)庫

2021-03-10 00:02:01

Redis

2021-10-18 07:43:30

RedisAOF日志RDB快照

2024-09-06 17:49:46

2023-03-13 08:08:48

數(shù)據(jù)庫Redis

2020-01-06 14:54:31

RDBAOFRedis

2024-09-29 09:25:53

2020-12-11 11:40:37

RDBAOFRedis

2021-02-04 08:01:35

RedisRDBAOF

2025-01-22 10:16:46

RedisRDBAOF

2025-03-14 10:22:26

2023-10-12 13:01:29

Redis數(shù)據(jù)庫

2020-03-03 14:15:49

Redis持久化數(shù)據(jù)庫

2020-02-18 16:14:33

RedisRDBAOF
點(diǎn)贊
收藏

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