1. 程式人生 > 其它 >RDB持久化 - 《Redis設計與實現》讀書筆記

RDB持久化 - 《Redis設計與實現》讀書筆記

RDB持久化功能:將Redis在記憶體中某一個時間點的資料庫狀態經過壓縮儲存到磁碟上的一個RDB二進位制檔案裡面,避免資料意外丟失,
通過RDB二進位制檔案可以還原生成RDB二進位制檔案那個時間點的資料庫狀態,

RDB檔案的建立: 記憶體 => 磁碟

  1. save命令: 阻塞Redis伺服器程序,直到RDB檔案建立完畢為止
    執行期間,伺服器程序不能處理客戶端命令請求

  2. bgsave命令: 派生出一個子程序,由子程序負責建立RDB檔案,
    執行期間,伺服器程序(父程序)仍然可以處理客戶端命令請求,
    出於程序競爭和效能問題,save、bgsave、bgrewriteaof命令不能同時執行

RDB檔案的載入: 磁碟 => 記憶體

RDB檔案的載入工作是在伺服器啟動時自動執行的,
執行路徑:src/server.c/main => src/server.c/loadDataFromDisk

如果伺服器開啟了AOF持久化功能,那麼伺服器會優先使用AOF檔案來還原資料庫狀態,
如果伺服器關閉了AOF持久化功能,那麼伺服器才會使用RDB檔案來還原資料庫狀態

自動間隔性儲存

通過設定伺服器配置的save選項,可以讓伺服器每隔一段時間自動執行一次bgsave命令,
save選項可以設定多個儲存條件,但只要任意一個條件被滿足,就會執行bgsave命令,

// 觸發儲存rdb檔案
for (j = 0; j < server.saveparamslen; j++) {
    struct saveparam *sp = server.saveparams+j;

    /* Save if we reached the given amount of changes,
        * the given amount of seconds, and if the latest bgsave was
        * successful or if, in case of an error, at least
        * CONFIG_BGSAVE_RETRY_DELAY seconds already elapsed. */
    if (
        // 是否達到了給定的更改量
        server.dirty >= sp->changes &&
        // 是否達到了給定的秒數
        server.unixtime-server.lastsave > sp->seconds &&
        // 上次嘗試bgsave的Unix時間是否已經過大於5秒 or 上次嘗試bgsave是否成功
        (server.unixtime-server.lastbgsave_try > CONFIG_BGSAVE_RETRY_DELAY || server.lastbgsave_status == C_OK))
    {
        serverLog(LL_NOTICE,"%d changes in %d seconds. Saving...",
            sp->changes, (int)sp->seconds);
        rdbSaveInfo rsi, *rsiptr;
        rsiptr = rdbPopulateSaveInfo(&rsi);
        // 執行rdb檔案儲存操作
        rdbSaveBackground(server.rdb_filename,rsiptr);
        break;
    }
}

分析RDB檔案

  1. 人工分析
    使用-cx引數呼叫od命令,同時以ASCII編碼和十六進位制格式列印RDB檔案
    od -cx check-dump.rdb
  1. 使用Redis帶有的RDB檔案檢查工具redis-check-dump

  2. 使用其它處理RDB檔案的工具

原始碼閱讀

  1. RDB檔案的建立: src/rdb.c/rdbSave
  2. RDB檔案載入: src/rdb.c/rdbLoad
隻言片語任我說,提筆句句無需忖。落筆不知寄何人,唯有邀友共斟酌。