為什麼需要持久化
Redis是基于記憶體的資料庫,它把資料存儲在記憶體當中,如果不想辦法把資料存放在磁盤當中,一旦Redis程序退出,記憶體中的資料也就消失了。
為了解決這個問題,Redis提供了兩種持久化方式,分别是RDB(Redis Database)和AOF(Append Only File)。
RDB持久化
RDB持久化是通過儲存key-value對來儲存Redis資料庫狀态。
RDB檔案的建立和載入
Redis有兩個指令可以用來生成RDB檔案。一個是SAVE,另個是BGSAVE。
SAVE:SAVE指令會阻塞Redis伺服器程序,直到RDB檔案建立完成,在這個期間,伺服器不能處理其他的指令請求,如果用戶端發送指令請求都會被拒絕。
BGSAVE:BFSAVE指令不會阻塞Redis程序,會派生出一個子程序,由這個子程序來負責建立RDB檔案,父程序可以繼續處理請求指令。
RDB檔案的加載不需要手動載入,啟動的時候如果檢測到RDB檔案存在,就會自動加載RDB檔案。
自動定時儲存原理
RDB持久化的方式是每間隔一段時間儲存資料。
設定儲存條件:
Redis伺服器啟動的時候,可以通過指定配置檔案或者傳入啟動參數來設定save條件。預設的條件是
save 900 1
save 300 10
save 60 10000
第一個條件是伺服器在900秒之内,對伺服器至少進行了一次修改。
三個條件隻要滿足一個,伺服器就會自動執行BFSAVE指令
伺服器會根據save選項設定的儲存條件,來設定redisServer結構裡面的saveparams數組,數組裡面的每一個元素是saveparam,裡面的内容是save選項裡面的儲存條件。三個儲存條件就會有三個saveparam元素。
伺服器維護一個dirty計數器和lastsave屬性。
dirty計數器的作用是記錄上一次成功執行SAVE或者BGSAVE之後,Redis資料庫進行了多少次修改。
lastsave是一個UNIX時間戳,記錄了上一次成功執行SAVE或者BGSAVE指令的時間。
Redsi伺服器有一個周期性操作函數serverCron,預設情況下,每個100毫秒就會執行一次,它會檢查saveparams數組裡面的儲存條件,隻要與一個條件滿足,伺服器就會執行BGSAVE指令。
AOF持久化
AOF是通過儲存所有修改資料庫的寫操作指令來記錄redis資料庫的狀态。
AOF持久化的實作主要分為指令追加,檔案寫入,檔案同步,三個步驟:
指令追加:如果AOF的持久化功能在打開狀态,伺服器執行完一個寫操作,就會把這個寫指令追加到伺服器狀态的aof_buf緩沖區的末尾。
檔案寫入和同步:
Redis的伺服器程序是一個事件循環。事件包括:檔案事件和時間事件。
時間時間負責執行需要定時運作的函數,比如serverCron函數。
檔案事件負責接收用戶端的指令請求,傳回結果。
伺服器在每一次時間結束循環之前,會調用flushAppendOnlyFile函數,考慮是否把aof_buf緩沖區的内容寫入到AOF檔案裡面。
flushAppendOnlyFile函數的行為,和配置項appendfsync有關。 預設情況下appendfsync配置成everysec。這樣持久化的行為就是:把aof_buf緩沖區的内容寫到AOF檔案,如果上一次同步AOF的檔案距離現在超過了一秒鐘,就會再次對AOF的内容進行同步,這個同步操作是由一個線程專門負責。