乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Redis系列(三):Redis的持久化機制(RDB、AOF)

       路人甲Java 2022-04-13

      本篇博客是Redis系列的第3篇,主要講解下Redis的2種持久化機制:RDB和AOF。

      本系列的前2篇可以點擊以下鏈接查看:

      Redis系列(一):Redis簡介及環(huán)境安裝。

      Redis系列(二):Redis的5種數(shù)據(jù)結(jié)構(gòu)及其常用命令

      1. 為什么需要持久化?

      因為Redis是內(nèi)存數(shù)據(jù)庫,它將自己的數(shù)據(jù)存儲在內(nèi)存里面,一旦Redis服務(wù)器進程退出或者運行Redis服務(wù)器的計算機停機,Redis服務(wù)器中的數(shù)據(jù)就會丟失。

      為了避免數(shù)據(jù)丟失,所以Redis提供了持久化機制,將存儲在內(nèi)存中的數(shù)據(jù)保存到磁盤中,用于在Redis服務(wù)器進程退出或者運行Redis服務(wù)器的計算機停機導(dǎo)致數(shù)據(jù)丟失時,快速的恢復(fù)之前Redis存儲在內(nèi)存中的數(shù)據(jù)。

      Redis提供了2種持久化方式,分別為:

      1. RDB持久化
      2. AOF持久化

      接下來,我們一一詳解。

      2. RDB持久化

      RDB持久化是將某個時間點上Redis中的數(shù)據(jù)保存到一個RDB文件中,如下所示:

      基于RDB持久化的上述性質(zhì),所以RDB持久化也叫做快照持久化。

      該文件是一個經(jīng)過壓縮的二進制文件,通過該文件可以還原生成RDB文件時Redis中的數(shù)據(jù),如下所示:

      2.1 創(chuàng)建RDB文件

      Redis提供了2個命令來創(chuàng)建RDB文件,一個是SAVE,另一個是BGSAVE。

      SAVE命令會阻塞Redis服務(wù)器進程,直到RDB文件創(chuàng)建完畢為止,在服務(wù)器進程阻塞期間,服務(wù)器不能處理任何命令請求,如下所示:

      BGSAVE命令會派生出一個子進程,然后由子進程負責創(chuàng)建RDB文件,服務(wù)器進程(父進程)繼續(xù)處理命令請求,如下所示:

      以上描述也是這2個命令的區(qū)別,這里是重點,面試經(jīng)常會問到。

      因為BGSAVE命令可以在不阻塞服務(wù)器進程的情況下執(zhí)行,所以推薦使用BGSAVE命令。

      我們可以手動執(zhí)行該命令,如上面截圖所示,但還是推薦設(shè)置下Redis服務(wù)器配置文件的save選項,讓服務(wù)器每隔一段時間自動執(zhí)行一次BGSAVE命令。

      我們可以通過save選項設(shè)置多個保存條件,只要其中任意一個條件被滿足,服務(wù)器就會執(zhí)行BGSAVE命令。

      save選項設(shè)置的默認條件如下所示:

      save 900 1

      save 300 10

      save 60 10000

      默認的配置條件表示,只要滿足以下3個條件中的任意1個,BGSAVE命令就會被執(zhí)行:

      • 服務(wù)器在900s(即15分鐘)之內(nèi),對數(shù)據(jù)庫進行了至少1次修改
      • 服務(wù)器在300s(即5分鐘)之內(nèi),對數(shù)據(jù)庫進行了至少10次修改
      • 服務(wù)器在60s(即1分鐘)之內(nèi),對數(shù)據(jù)庫進行了至少10000次修改

      當滿足條件執(zhí)行BGSAVE命令時,輸出日志如下圖所示:

      生成的RDB文件會根據(jù)Redis配置文件中的名稱和路徑來保存,相關(guān)的2個配置如下所示:

      最終生成的RDB文件如下所示(截圖為本機Windows環(huán)境,Linux環(huán)境下路徑會稍有不同):

      2.2 載入RDB文件

      首先,我們要明確的是,載入RDB文件的目的是為了在Redis服務(wù)器進程重新啟動之后還原之前存儲在Redis中的數(shù)據(jù)。

      然后,Redis載入RDB文件并沒有專門的命令,而是在Redis服務(wù)器啟動時自動執(zhí)行的。

      而且,Redis服務(wù)器啟動時是否會載入RDB文件還取決于服務(wù)器是否啟用了AOF持久化功能,具體判斷邏輯為:

      1. 只有在AOF持久化功能處于關(guān)閉狀態(tài)時,服務(wù)器才會使用RDB文件來還原數(shù)據(jù)。
      2. 如果服務(wù)器開啟了AOF持久化功能,那么服務(wù)器會優(yōu)先使用AOF文件來還原數(shù)據(jù)。

      以上判斷邏輯如下圖所示:

      默認情況下,Redis服務(wù)器的AOF持久化功能是關(guān)閉的,所以Redis服務(wù)器在啟動時會載入RDB文件,

      啟動日志如下所示:

      2.3 服務(wù)器狀態(tài)

      創(chuàng)建和載入RDB文件,可能存在的服務(wù)器狀態(tài)有以下3種:

      1. 當執(zhí)行SAVE命令時,Redis服務(wù)器會被阻塞,此時客戶端發(fā)送的所有命令請求都會被阻塞,只有在服務(wù)器執(zhí)行完SAVE命令,重新開始接受命令請求之后,客戶端發(fā)送的命令請求才會被處理。
      2. 當執(zhí)行BGSAVE命令時,Redis服務(wù)器不會被阻塞,Redis服務(wù)器仍然可以繼續(xù)處理客戶端發(fā)送的命令請求。
      3. 服務(wù)器在載入RDB文件期間,會一直處于阻塞狀態(tài),直到RDB文件載入成功。

      3. AOF持久化

      AOF持久化是通過保存Redis服務(wù)器所執(zhí)行的寫命令來記錄數(shù)據(jù)庫數(shù)據(jù)的,如下圖所示:

      默認情況下,AOF持久化功能是關(guān)閉的,如果想要打開,可以修改下圖所示的配置:

      舉個例子,假設(shè)Redis中還沒有存儲任何數(shù)據(jù),我們執(zhí)行了如下所示的命令:

      然后我們會發(fā)現(xiàn)Redis服務(wù)器生成了1個名為appendonly.aof的文件,打開該文件,我們可以看到上面執(zhí)行的3個寫命令都存儲在該文件中:

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

      當AOF持久化功能處于打開狀態(tài)時,Redis服務(wù)器在執(zhí)行完一個寫命令之后,會以協(xié)議格式(如上面截圖中AOF文件里保存寫命令的格式)將被執(zhí)行的寫命令追加到服務(wù)器狀態(tài)的AOF緩沖區(qū)的末尾,然后Redis服務(wù)器會根據(jù)配置文件中appendfsync選項的值來決定何時將AOF緩沖區(qū)中的內(nèi)容寫入和同步到AOF文件里面。

      appendfsync選項有以下3個值:

      1. always

        從安全性來說,always是最安全的(丟失數(shù)據(jù)最少),因為即使出現(xiàn)故障停機,數(shù)據(jù)庫也只會丟失一個事件循環(huán)中所產(chǎn)生的命令數(shù)據(jù)。

        從效率來說,always的效率最慢,因為服務(wù)器在每個事件循環(huán)都要將AOF緩沖區(qū)中的所有內(nèi)容寫入到AOF文件,并且同步AOF文件。

      2. everysec

        從安全性來說,everysec模式下,即使出現(xiàn)故障停機,數(shù)據(jù)庫只會丟失一秒鐘的命令數(shù)據(jù)。

        從效率來說,everysec模式足夠快,因為服務(wù)器在每個事件循環(huán)都要將AOF緩沖區(qū)中的所有內(nèi)容寫入到AOF文件,并且每隔一秒就要在子線程中對AOF文件進行同步。

      3. no

        從安全性來說,no模式下,如果出現(xiàn)故障停機,數(shù)據(jù)庫會丟失上次同步AOF文件之后的所有寫命令數(shù)據(jù),具有不確定性,因為服務(wù)器在每個事件循環(huán)都要將AOF緩沖區(qū)中的所有內(nèi)容寫入到AOF文件,至于何時對AOF文件進行同步,則由操作系統(tǒng)控制。

        從效率來說,no模式和everysec模式的效率差不多。

      appendfsync選項的默認值是everysec,也推薦使用這個值,因為既保證了效率又保證了安全性。

      3.2 載入AOF文件

      因為AOF文件包含了重建數(shù)據(jù)庫所需的所有寫命令,所以Redis服務(wù)器只要讀入并重新執(zhí)行一遍AOF文件里面保存的寫命令,就可以還原Redis服務(wù)器關(guān)閉之前的數(shù)據(jù)。

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

      1. 創(chuàng)建一個不帶網(wǎng)絡(luò)連接的偽客戶端

        因為Redis的命令只能在客戶端上下文中執(zhí)行,而載入AOF文件時所使用的命令直接來源于AOF文件而不是網(wǎng)絡(luò)連接,所以服務(wù)器使用了一個沒有網(wǎng)絡(luò)連接的偽客戶端來執(zhí)行AOF文件保存的寫命令。

        偽客戶端執(zhí)行命令的效果和帶網(wǎng)絡(luò)連接的客戶端執(zhí)行命令的效果完全一樣。

      2. 從AOF文件中分析并讀取出一條寫命令。

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

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

      以上步驟如下圖所示:

      如果Redis服務(wù)器開啟了AOF持久化功能,那么Redis服務(wù)器在啟動時會載入AOF文件,

      啟動日志如下所示:

      3.3 AOF重寫

      因為AOF持久化是通過保存被執(zhí)行的寫命令來記錄數(shù)據(jù)庫數(shù)據(jù)的,所以隨著Redis服務(wù)器運行時間的增加,AOF文件中的內(nèi)容會越來越多,文件的體積會越來越大,如果不做控制,會有以下2點壞處:

      1. 過多的占用服務(wù)器磁盤空間,可能會對Redis服務(wù)器甚至整個宿主計算機造成影響。
      2. AOF文件的體積越大,使用AOF文件來進行數(shù)據(jù)庫還原所需的時間就越多。

      舉個例子,在客戶端執(zhí)行如下命令:

      為了記錄這個list鍵的狀態(tài),AOF文件就需要保存上面執(zhí)行的6條命令。

      為了解決AO文件體積越來越大的問題,Redis提供了AOF文件重寫功能,即Redis服務(wù)器會創(chuàng)建一個新的AOF文件來替代現(xiàn)有的AOF文件,新舊兩個AOF文件所保存的數(shù)據(jù)庫數(shù)據(jù)相同,但新AOF文件不會包含任何浪費空間的冗余命令,所以新AOF文件的體積通常會比舊AOF文件的體積要小很多。

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

      AOF文件重寫并不需要對現(xiàn)有的AOF文件進行任何讀取、分析或者寫入操作,而是通過讀取服務(wù)器當前的數(shù)據(jù)庫數(shù)據(jù)來實現(xiàn)的。

      仍然以上面的list鍵為例,舊的AOF文件保存了6條命令來記錄list鍵的狀態(tài),但list鍵的結(jié)果是“C” "D" "E" "F" "G"這樣的數(shù)據(jù),所以AOF文件重寫時,可以用一條RPUSH list “C” "D" "E" "F" "G"命令來代替之前的六條命令,這樣就可以將保存list鍵所需的命令從六條減少為一條了。

      按照上面的原理,如果Redis服務(wù)器存儲的鍵值對足夠多,AOF文件重寫生成的新AOF文件就會減少很多很多的冗余命令,進而大大減小了AOF文件的體積。

      綜上所述,AOF文件重寫功能的實現(xiàn)原理為:

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

      3.3.2 AOF后臺重寫

      因為AOF文件重寫會進行大量的文件寫入操作,所以執(zhí)行這個操作的線程將被長時間阻塞。

      因為Redis服務(wù)器使用單個線程來處理命令請求,所以如果由服務(wù)器進程直接執(zhí)行這個操作,那么在重寫AOF文件期間,服務(wù)器將無法處理客戶端發(fā)送過來的命令請求。

      為了避免上述問題,Redis將AOF文件重寫功能放到子進程里執(zhí)行,這樣做有以下2個好處:

      1. 子進程進行AOF文件重寫期間,服務(wù)器進程(父進程)可以繼續(xù)處理命令請求。
      2. 子進程帶有服務(wù)器進程的數(shù)據(jù)副本,使用子進程而不是線程,可以在避免使用鎖的情況下,保證數(shù)據(jù)的安全性。

      AOF后臺重寫的步驟如下所示:

      1. 服務(wù)器進程創(chuàng)建子進程,子進程開始AOF文件重寫

      2. 從創(chuàng)建子進程開始,服務(wù)器進程執(zhí)行的所有寫命令不僅要寫入AOF緩沖區(qū),還要寫入AOF重寫緩沖區(qū)

        寫入AOF緩沖區(qū)的目的是為了同步到原有的AOF文件。

        寫入AOF重寫緩沖區(qū)的目的是因為子進程在進行AOF文件重寫期間,服務(wù)器進程還在繼續(xù)處理命令請求,

        而新的命令可能會對現(xiàn)有的數(shù)據(jù)庫進行修改,從而使得服務(wù)器當前的數(shù)據(jù)庫數(shù)據(jù)和重寫后的AOF文件所

        保存的數(shù)據(jù)庫數(shù)據(jù)不一致。

      3. 子進程完成AOF重寫工作,向父進程發(fā)送一個信號,父進程在接收到該信號后,會執(zhí)行以下操作:

        1.將AOF重寫緩沖區(qū)中的所有內(nèi)容寫入到新AOF文件中,這樣就保證了新AOF文件所保存的數(shù)據(jù)庫數(shù)據(jù)和服務(wù)器當前的數(shù)據(jù)庫數(shù)據(jù)是一致的。

        2.對新的AOF文件進行改名,原子地覆蓋現(xiàn)有的AOF文件,完成新舊兩個AOF文件的替換。

      Redis提供了BGREWRITEAOF命令來執(zhí)行以上步驟,如下圖所示:

      執(zhí)行完成后,打開appendonly.aof文件,發(fā)現(xiàn)保存list鍵的命令從六條變?yōu)榱艘粭l:

      除了手動執(zhí)行BGREWRITEAOF命令外,Redis還提供了2個配置項用來自動執(zhí)行BGREWRITEAOF命令:

      auto-aof-rewrite-percentage 100

      auto-aof-rewrite-min-size 64mb

      該配置表示,當AOF文件的體積大于64MB,并且AOF文件的體積比上一次重寫之后的體積大了至少一倍(100%),Redis將自動執(zhí)行BGREWRITEAOF命令。

      4. RDB持久化、AOF持久化的區(qū)別

      通過上面的講解,我們會發(fā)現(xiàn)Redis提供的2種持久化方法是有區(qū)別的,可以總結(jié)為以下4點:

      1. 實現(xiàn)方式
      2. 文件體積
      3. 安全性
      4. 優(yōu)先級

      接下來一一講解。

      4.1 實現(xiàn)方式

      RDB持久化是通過將某個時間點Redis服務(wù)器存儲的數(shù)據(jù)保存到RDB文件中來實現(xiàn)持久化的。

      AOF持久化是通過將Redis服務(wù)器執(zhí)行的所有寫命令保存到AOF文件中來實現(xiàn)持久化的。

      4.2 文件體積

      由上述實現(xiàn)方式可知,RDB持久化記錄的是結(jié)果,AOF持久化記錄的是過程,所以AOF持久化生成的AOF文件會有體積越來越大的問題,Redis提供了AOF重寫功能來減小AOF文件體積。

      4.3 安全性

      AOF持久化的安全性要比RDB持久化的安全性高,即如果發(fā)生機器故障,AOF持久化要比RDB持久化丟失的數(shù)據(jù)要少。

      因為RDB持久化會丟失上次RDB持久化后寫入的數(shù)據(jù),而AOF持久化最多丟失1s之內(nèi)寫入的數(shù)據(jù)(使用默認everysec配置的話)。

      4.4 優(yōu)先級

      由于上述的安全性問題,如果Redis服務(wù)器開啟了AOF持久化功能,Redis服務(wù)器在啟動時會使用AOF文件來還原數(shù)據(jù),如果Redis服務(wù)器沒有開啟AOF持久化功能,Redis服務(wù)器在啟動時會使用RDB文件來還原數(shù)據(jù),所以AOF文件的優(yōu)先級比RDB文件的優(yōu)先級高。

      5. 源碼及參考

      Josiah L. Carlson 《Reids實戰(zhàn)》

      黃健宏 《Redis設(shè)計與實現(xiàn)》

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多