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
備份流程:
-
處理命令請求和響應
-
處理事件時間(
Server Cron
函式) -
判斷是否要寫入
AOF
(具體由配置決定) -
將
aof_buf
中的內容寫入到磁碟中具體流程:
-
appendfsync always
將
aof_buf
中的內容寫入並且同步到AOF
檔案中,真正把指令存入了磁碟。優點:資料不會丟失
缺點:效率低
-
appendfsync everysec
將
aof_buf
中的內容寫入到AOF
檔案。上次同步時間距離現在時間超過 1 s,則執行AOF
同步 -
appendfsync no
將 aof_buf
中的內容寫入到 AOF
AOF
同步,由作業系統決定
AOF
恢復流程:
-
建立一個偽客戶端
-
讀取
AOF
檔案中的命令資料,依次執行 -
當所有命令都被執行完成時,流程結束
具體流程:
作業系統層面寫入與同步:
-
呼叫系統函式
write
,將內容寫入到作業系統緩衝區 -
作業系統決定何時將緩衝區內的資料寫入到磁碟
具體流程如下所示:
AOF
重寫
AOF
存在的缺陷:
AOF
越來越大,造成空間的浪費,資料載入也會非常慢- 多條執行的命令,有很大的機率都是多餘的
解決方案:
-
AOF
重寫:通過讀取Redis
中存在的鍵的值,轉換為對應的Redis
命令再儲存到AOF
檔案中- 配置
// 比上次重寫後的比例增加了 100% auto-aof-rewrite-percentage 100 // 並且 aof 檔案體積超過 64mb 的情況下,才會發生重寫 auto-aof-rewrite-min-size 64mb
通過
fork
一個子程序進行AOF
重寫。使得主程序不會被阻塞針對資料不一致的情況,
Redis
設定了一個AOF
重寫緩衝區,子程序在建立時會使用該緩衝區內的內容。具體流程如下:
-
首先判斷是否滿足重寫
AOF
的條件,如果不滿足,那麼執行一般的AOF
寫入,將輸入的命令儲存到AOF
緩衝區,再進行進一步的寫入磁碟操作 -
如果滿足重寫
AOF
的條件,那麼就執行AOF
重寫。此時主程序將會fork
一個子程序,讓子程序完成重寫的操作。 -
然而
fork
子程序之後主程序依舊要接收命令,因此在fork
一個子程序之後將會建立一個AOF
重寫緩衝區,再fork
子程序之後的所有命令都會寫入到這個緩衝區。 -
當子程序完成
AOF
的重寫任務之後,將會給主程序傳送一個訊號,使得主程序將AOF
重寫緩衝區內的內容新增到子程序寫入的新的AOF
檔案中 -
最後使用新的
AOF
檔案替換掉舊的AOF
檔案,完成AOF
的重寫任務注意:在主程序處理子程序傳送的訊號和將
AOF
緩衝區內容寫入到新的AOF
檔案中的過程中,主程序是阻塞的