Redis(五)--- Redis的持久化RDB與AOF

1、Redis數據庫

咱們都知道Redis是基於內存的數據庫,數據是以key-value鍵值對的方式存儲的,那麼key-value鍵值對是隨意放在內存中的麼,其實Redis的服務會建立不少的數據庫空間,這些key-value鍵值對都是在各個數據庫空間中存儲的。redis

當咱們使用客戶端工具連接Redis服務時,會在客戶端中看到一系列的db*命名的項(如圖),這些就是一個個數據庫,Redis初始化建立16個數據庫,數據庫建立個數能夠在配置文件中修改。數據庫

而在命令行模式中是看不到這些數據庫的具體數量的,但在命令行提示符的右側會提示咱們當前處於哪一個數據庫(如圖),而且能夠用上一章說到的SELECT命令進行數據庫的切換;客戶端默認鏈接第一個數據庫,即0號數據庫。安全

(1)數據庫鍵空間服務器

key-value鍵值對存儲在各個數據庫中,而每一個數據庫內部都是由一個redisDb結構,結構中有若干個屬性,最主要的有兩個屬性dict、expires。網絡

1 typedef struct redisDb {
2     // ...
3     // 數據庫鍵空間,保存着數據庫中的全部鍵值對
4     dict *dict;
5 
6     // 過時字典,保存着鍵的過時時間
7     dict *expires;
8     // ...
9 } redisDb;
    • dict 是字典結構,存儲咱們的key-value鍵值對,這個字典稱爲數據庫鍵空間,字典的鍵就是數據庫的鍵,每一個鍵都是一個字符串,存儲key值;字典的值就是數據庫的值,每一個值均可以是五大對象中任意一種,存儲value值;因此咱們存儲的key-value最終是在數據庫中以字典的結構存儲的。
    • expires 一樣是字典結構,但其存儲的是key-value過時時間;當咱們設置了key-value的過時時間,那麼key-value存儲在dict字典中,而過時時間則存儲在expires中;字典的鍵存儲key,字典的值存儲過時時間;這裏須要注意的是,不管設置的過時時間是秒仍是毫秒,最終存儲時都會轉換爲unix毫秒時間戳。

圖中是帶有過時字典的數據庫例子數據結構

(2)持久化併發

上面說道的不管是數據庫仍是期內的數據都是存儲在服務器內內存中的,若是服務器一旦發生掉電,進程退出等狀況,那麼其內存中的數據就都消失不見了,在咱們大規模併發的項目下,顯然這是災難性的,因此應對這種狀況的辦法之一,就是持久化,把內存中的數放到磁盤中,意外發生後,可以從磁盤上進行數據恢復到內存中,這樣就避免了數據丟失。異步

Redis提供了兩種持久化方式RDB持久化和AOF持久化。工具

二、RDB持久化

RDB持久化是最直接的持久化方式,直接將內存中的數據保存到RDB文件中,當恢復時也是直接從RDB文件中恢復;spa

                      

 

    • RDB文件是通過壓縮的二進制文件,這裏對文件結構不作詳解。
    • RDB持久化能夠手動執行,也能夠設置按期執行。
    • RDB持久化命令有兩個SAVE(同步)和BGSAVE(異步),同步持久化過程當中,會拒絕客戶端的全部請求;異步則是建立子進程執行,不會對客戶端產生影響,具體能夠看上一章的命令介紹。

自動間隔性保存

由於BGSAVE命令是異步執行,不會阻塞服務器,因此Redis容許用戶自行配置SAVE選項,當選項觸發時自動執行BGSAVE命令。 

當用戶開啓了觸發自動BGSAVE後,若是不配置save選項,服務器會使用默認設置,以下:

  (1)在900秒內,對數據庫進行了至少1次修改。

(2)在300秒內,對數據庫進行了至少10次修改。

(3)在60秒內,對數據庫進行了至少10000次修改。

以上三個條件,知足任意一條,就會進行BGSAVE操做

三、AOF持久化

AOF持久化與RDB不一樣,AOF持久化是經過記錄服務器所執行的命令來保存數據的。

    • 被寫入AOF文件的全部命令都是以Redis請求協議格式保存的。
    • 數據的還原,就是經過讀取AOF文件的這些命令進行的。
    • 執行的命名並非直接寫入AOF文件的,而是先寫入緩衝區,沒執行一條命令就會追加到緩衝區的末尾,當一條命令執行完成後,返回數據前,會將緩衝區的數據寫入到AOF文件中。

AOF文件的載入與還原

AOF持久化的數據還原過程就是讀取AOF中命令從新執行命令的過程。

(1)Redis會建立一個僞客戶端,僞客戶端與真實的客戶端執行命令的效果是同樣的,只是不帶網絡鏈接。

(2)從AOF文件分析並讀取一條命令。

(3)僞客戶端執行這條命令。

(4)重複2和3過程,知道AOF文件中的全部命令處理完成。

AOF文件重寫

AOF文件的持久化是記錄被執行對的命令,這樣隨着時間愈來愈長,AOF文件中的內容會愈來愈多,體積也會愈來愈大,文件越大恢復數據的時間也越多。

在命令執行的過程當中有些鍵值對被刪除了,有些被修改了,而這些過程命令是徹底沒有必要再執行一遍的,因此Redis提供了AOF文件的重寫功能對AOF進行重建,使用重建後的文件要比元AOF文件體積小不少。

    • AOF文件重寫,並不須要對原AOF文件進行任何訪問改動,他是經過對數據庫內的數據讀取來操做的,即查看數據庫內有什麼數據,而後根據數據類型進行建立這些數據的寫入命令。
    • AOF文件重寫過程當中,建立寫入命令時會先檢查元素數量,若是數量超過了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD=64常量的值,就會分紅多條命令,
    • AOF文件重寫是有子進程進行的,並不影響主進程處理命令;子進程而不是線程,由於進程帶有數據副本,不鎖數據的狀況下,能保證安全。
    • AOF文件子進程重寫過程當中,主進程仍然在處理數據,這樣形成了子進程和主進程的數據不一致,子進程數據少了一部分,這種狀況下Redis會建立一個AOF重寫緩衝區;這樣少的那部分命令會寫到AOF重寫緩衝區中,重寫完成後,再把緩衝區這些命令寫進新的AOF文件中,而後用新的AOF文件替換就得AOF文件。

四、總結

    • Redis初始化會建立一批數據庫,每一個數據庫的內部數據結構都是字典,key-value的最終存儲也會落到字典上。
    • AOF持久化比RDB持久化頻率更高、速度更快;當有AOF持久化時,RDB持久化命令不會再執行;但當RDB持久化命令執行時,AOF命令會等待其執行完成後再執行,而其餘RDB命令不會執行。
    • AOF文件重寫過程不會影響舊的AOF文件,即使AOF重寫過程失敗,也不會干擾原來的AOF恢復數據,只有在成功以後纔會替換原來的文件。

 

參考:

《Redis設計與實現》黃健宏著,網上對Redis的詳解等

此博客爲筆者使用redis好久以後,參考網絡上各種文章總結性書寫,原創手打,若有錯誤歡迎指正。

相關文章
相關標籤/搜索