日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

《Redis设计与实现》之第十一章:AOF持久化

發(fā)布時間:2025/3/20 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Redis设计与实现》之第十一章:AOF持久化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

AOF持久化是通過保存Redis服務器所執(zhí)行的寫命令來記錄數(shù)據(jù)庫狀態(tài)的。被寫入AOF文件的所有命令都是以Redis的命令請求協(xié)議格式(純文本)保存的。

一,AOF持久化的實現(xiàn)

1.命令追加

當AOF持久化功能處于打開狀態(tài)時,服務器在執(zhí)行完一個寫命令后,會以協(xié)議格式把被執(zhí)行的寫命令追加到服務器狀態(tài)的aof_buf緩沖區(qū)的末尾:

struct redisServer{

  //AOF緩沖區(qū)

  sds aof_buf;

}

2.AOF文件的寫入和同步

命令請求會先保存到AOF緩沖區(qū)中,然后在寫入并同步到AOF文件。

Redis服務器進程是一個事件循環(huán),在這個循環(huán)中有文件事件,有時間事件。文件事件負責接收客戶端的命令請求和向客戶端發(fā)送命令回復。時間事件負責執(zhí)行定時運行的函數(shù),比如:serverCron函數(shù)。

偽代碼:

def eventLoop():

  while true:

    //處理文件事件,接收命令請求以及發(fā)送命令回復。處理命令請求時可能會有新內(nèi)容被追加到aof_buf緩沖區(qū)中

    processFileEvents()

    //處理時間事件

    processTimeEvents()

    //考慮是否要把 aof_buf中的內(nèi)容寫入和保存到AOF文件中

    flushAppendOnlyFile()

?

寫入:在現(xiàn)代操作系統(tǒng)中,當數(shù)據(jù)寫入到文件中時,會調(diào)用write函數(shù)。操作系統(tǒng)會將寫入數(shù)據(jù)暫時保存在一個內(nèi)存緩存區(qū)中,等到緩沖區(qū)空間滿的時候,才真正將緩沖區(qū)中的數(shù)據(jù)寫入到磁盤中。

同步:同時系統(tǒng)也提供了同步函數(shù),它可以強制讓操作系統(tǒng)立即將緩沖區(qū)中的數(shù)據(jù)寫入到磁盤中。

?

由上面的代碼可以知道,在每個事件循環(huán)都會調(diào)用flushAppendOnlyFile函數(shù),flushAppendOnlyFile函數(shù)的行為由appendfsync的值決定:

always:服務器在每個事件循環(huán)都要將aof_buf緩沖區(qū)中的所有內(nèi)容寫入到AOF文件中,并同步AOF文件(寫入并同步)(,把aof_buf數(shù)據(jù)寫入并同步到AOF文件中)

everysec:服務器在每個事件循環(huán)都要將aof_buf緩沖區(qū)中的所有內(nèi)容寫入到AOF文件中(先寫入),并且每隔一秒就在子線程中對AOF文件進行一次同步(每隔一秒同步)。

no:服務器在每個事件循環(huán)都要將aof_buf緩沖區(qū)中的所有內(nèi)容寫入到AOF文件中(先寫入),至于什么時候同步,由操作系統(tǒng)控制(不知道啥時候同步)。在該模式下的flushAppendOnlyFile的調(diào)用不需要同步執(zhí)行。

?

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

1.數(shù)據(jù)還原:AOF文件中包含了重建數(shù)據(jù)庫狀態(tài)的所有寫命令,所以服務器只要讀入并重新執(zhí)行一遍AOF文件里保存的寫命令,就可以還原數(shù)據(jù)

2.步驟:

創(chuàng)建一個不帶網(wǎng)絡連接的偽客戶端。(為什么是為客戶端:Redis的命令只能在客戶端上下文中執(zhí)行,為什么是不帶網(wǎng)絡連接:命令來自AOF文件而不是網(wǎng)絡連接)

從AOF文件中分析并讀取一條寫命令

使用偽客戶端執(zhí)行被讀出的寫命令

一直執(zhí)行步驟2,3 。直到AOF文件中的所有寫命令都被處理完畢

?

三,AOF重寫

1.什么是AOF重寫?

為了解決AOF文件體積膨脹,Redis服務器創(chuàng)建一個新的AOF文件替代現(xiàn)有的AOF文件,新舊兩個文件保存的數(shù)據(jù)庫狀態(tài)相同,但是新AOF文件不會包含冗余命令。

Redis把新AOF文件替換舊AOF文件的功能叫 AOF文件重寫。

2.AOF文件重寫的實現(xiàn)

注意:AOF文件重寫并不需要對現(xiàn)有的AOF文件進行如何讀取,分析或?qū)懭氩僮?#xff0c;這個功能是通過讀取服務器當前的數(shù)據(jù)庫狀態(tài)來實現(xiàn)的。

原理:首先從數(shù)據(jù)庫中讀取鍵現(xiàn)在的值,然后用一條命令記錄鍵值對,代替之前記錄這個鍵值對的多條命令。

【如果服務器想要用盡量少的命令來記錄鍵的狀態(tài),那么最簡單的辦法不是去讀取和分析現(xiàn)有AOF文件的內(nèi)容,而是直接從數(shù)據(jù)庫中讀取鍵的值,然后用一條寫命令來替代保存在AOF文件中的多條寫命令,這樣就可以把保存鍵的多條命令減少為一條。】

在實際中,為了避免在執(zhí)行命令時造成客戶端輸入緩沖區(qū)溢出。在處理有多個元素的鍵時,會先檢查鍵包含的元素數(shù)量,如果超過了一定的值,會使用多條命令來記錄鍵的值。比如一個列表鍵包含了超過64個項,那么重寫程序會用多條rpush命令來保存這個列表。

3.AOF后臺重寫

問題:由于Redis服務器使用單個線程處理命令請求,當服務器調(diào)用aof_rewrite函數(shù)時,在重寫AOF文件期間,服務器無法處理客戶端發(fā)送來的命令請求

解決:把AOF重寫程序放到子進程中執(zhí)行,這樣子進程重寫期間,父進程可以繼續(xù)處理命令請求。并且子進程帶有父進程的數(shù)據(jù)副本。

那么問題又來了:在子進程進行AOF重寫期間,服務器進程在處理命令請求時可能會改變數(shù)據(jù)庫狀態(tài),導致服務器當前數(shù)據(jù)庫狀態(tài)和重寫后的AOF文件保存的數(shù)據(jù)庫狀態(tài)不一致

為了解決數(shù)據(jù)不一致問題,Redis服務器設置了一個AOF重寫緩沖區(qū),這個緩沖區(qū)在創(chuàng)建子進程之后使用,當Redis服務器執(zhí)行完一個寫命令后,會同時把這個寫命令發(fā)送給AOF緩沖區(qū)和AOF重寫緩沖區(qū)。

在子進程執(zhí)行AOF重寫期間,服務器需要:

執(zhí)行客戶端發(fā)送過來的命令

將執(zhí)行后的寫命令追加到AOF緩沖區(qū)

將執(zhí)行后的寫命令追擊到AOF重寫緩沖區(qū)

當子進程完成重寫工作后,向父進程發(fā)送一個信號,父進程在接到這個信號后,把AOF重寫緩沖區(qū)中的所有內(nèi)容寫到新AOF文件中,并對新的AOF文件進行改名,覆蓋現(xiàn)有的AOF文件。

?

轉(zhuǎn)載于:https://www.cnblogs.com/inspred/p/10676708.html

總結(jié)

以上是生活随笔為你收集整理的《Redis设计与实现》之第十一章:AOF持久化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。