1. 程式人生 > 其它 >Redis資料持久化

Redis資料持久化

Redis 資料持久化

RDB

支援手工執行和服務端定期執行。持久化的內容為二進位制資料檔案

// server.h
struct redisServer {
    ……………………
    // 儲存 saveparams 陣列
    struct saveparam *saveparams;   /* Save points array for RDB */
    // 修改記錄計數器,記錄上一次成功執行 SAVE 或者 BGSAVE 後,資料進行了多少次修改(包括寫入、刪除、更新等操作)
    long long dirty;                /* Changes to DB from the last save */
    
    // 上一次執行儲存的時間,記錄上一次成功執行 SAVE 或者 BGSAVE 的時間
    time_t lastsave;                /* Unix time of last successful save */
    ……………………
};

// server.h
struct saveparam {
    // 執行的秒數
    time_t seconds;
    // 修改的次數
    int changes;
    // 只有在兩個條件都滿足的情況下,才會執行一次儲存操作
    // 具體配置為 save <seconds> <changes> (redis.conf)
};

AOF

AOF:Append Only File。通過記錄 Redis 命令來記錄資料庫的變更

客戶端——> Redis 伺服器 ——> 執行命令 ——> 儲存執行的i命令 ——> AOF 檔案

// server.h
struct redisServer {
    …………………………
    sds aof_buf;      /* AOF buffer, written before entering the event loop */
    …………………………
};

aof_buf :在 redis.conf 中配置 AOF ,開啟 AOF,每次執行完命令,就會把命令寫入到 aof_buf

中。

AOF 備份流程:

  1. 處理命令請求和響應

  2. 處理事件時間(Server Cron 函式)

  3. 判斷是否要寫入 AOF(具體由配置決定)

  4. aof_buf 中的內容寫入到磁碟中

    具體流程:

  • appendfsync always

    aof_buf 中的內容寫入並且同步到 AOF 檔案中,真正把指令存入了磁碟。

    優點:資料不會丟失

    缺點:效率低

  • appendfsync everysec

    aof_buf 中的內容寫入到 AOF 檔案。上次同步時間距離現在時間超過 1 s,則執行 AOF 同步

  • appendfsync no

aof_buf 中的內容寫入到 AOF

檔案。但是不對 AOF 同步,由作業系統決定

AOF恢復流程:

  1. 建立一個偽客戶端

  2. 讀取 AOF 檔案中的命令資料,依次執行

  3. 當所有命令都被執行完成時,流程結束

    具體流程:

作業系統層面寫入與同步:

  1. 呼叫系統函式 write,將內容寫入到作業系統緩衝區

  2. 作業系統決定何時將緩衝區內的資料寫入到磁碟

    具體流程如下所示:

AOF 重寫

AOF 存在的缺陷:

  1. AOF 越來越大,造成空間的浪費,資料載入也會非常慢
  2. 多條執行的命令,有很大的機率都是多餘的

解決方案:

  • AOF 重寫:通過讀取 Redis 中存在的鍵的值,轉換為對應的 Redis 命令再儲存到 AOF 檔案中

    • 配置
    // 比上次重寫後的比例增加了 100%
    auto-aof-rewrite-percentage 100
    // 並且 aof 檔案體積超過 64mb 的情況下,才會發生重寫
    auto-aof-rewrite-min-size 64mb
    

    通過 fork 一個子程序進行 AOF 重寫。使得主程序不會被阻塞

    針對資料不一致的情況,Redis 設定了一個 AOF 重寫緩衝區,子程序在建立時會使用該緩衝區內的內容。

    具體流程如下:

  1. 首先判斷是否滿足重寫 AOF 的條件,如果不滿足,那麼執行一般的 AOF 寫入,將輸入的命令儲存到 AOF 緩衝區,再進行進一步的寫入磁碟操作

  2. 如果滿足重寫 AOF 的條件,那麼就執行 AOF 重寫。此時主程序將會 fork 一個子程序,讓子程序完成重寫的操作。

  3. 然而 fork 子程序之後主程序依舊要接收命令,因此在 fork一個子程序之後將會建立一個 AOF 重寫緩衝區,再 fork 子程序之後的所有命令都會寫入到這個緩衝區。

  4. 當子程序完成AOF 的重寫任務之後,將會給主程序傳送一個訊號,使得主程序將 AOF 重寫緩衝區內的內容新增到子程序寫入的新的 AOF 檔案中

  5. 最後使用新的 AOF 檔案替換掉舊的 AOF 檔案,完成 AOF 的重寫任務

    注意:在主程序處理子程序傳送的訊號和將 AOF 緩衝區內容寫入到新的 AOF 檔案中的過程中,主程序是阻塞的