Redis官方提供了兩種資料持久化的方式,分別是:RDB和AOF,今天我們來討論一下這兩種持久化方式的區別,
RDB
基本原理:RDB持久化主要是通過SAVE和BGSAVE兩個命令對Redis資料庫中當前的資料做snapshot并生成rdb檔案來實作的,其中SAVE是阻塞的,BGSAVE是非阻塞的,通過fork了一個子行程來完成的,在Redis啟動的時候會檢測rdb檔案,然后載入rdb檔案中未過期的資料到服務器中
配置資訊:RDB可以通過向服務器提供配置資訊來自動間隔性保存,如默認情況下服務器滿足以下3個條件中任意一個條件就會觸發BGSAVE命令
save 900 1 // 服務器在900秒之內,對資料庫進行了至少1次修改
save 300 10 // 服務器在300秒之內,對資料庫進行了至少10次修改
save 60 10000 // 服務器在60秒之內,對資料庫進行了至少10000次修改
實作方式:服務器通過維護dirty計數器和lastsave屬性分別記錄距離上次成功執行SAVE或者BGSAVE命令之后,服務器對資料庫狀態進行修改的次數和最后一次成功SAVE或者BGSAVE的UNIX時間戳,由Redis周期性操作函式serverCron默認每隔100ms來檢測是否滿足配置資訊中的要求,然后再決定是否執行SAVE或者BGSAVE命令來對資料庫進行備份,
AOF
基本原理:AOF(Append Only File)持久化是通過將存盤每次執行的客戶端命令,然后由一個偽客戶端來執行這些命令將資料寫入到服務器中的方式實作的,一共分為命令追加(append)、檔案寫入、檔案同步(sync)三個步驟完成的
命令追加
當有修改、洗掉操作時,服務器會在執行完之后以協議格式將被執行的寫命令追加到服務器狀態的aof_buf緩沖區的末尾
檔案寫入
Redis的服務行程就是一個事件回圈,這個回圈中的檔案事件負責接收客戶端的命令請求,服務器在處理檔案事件時可能會執行寫命令,同時會追加到aof_buf緩沖區,所以在每結束一次回圈之前,都會呼叫flushAppendOnlyFile函式,將aof_buf緩沖區的資料寫入到AOF檔案里面,
檔案同步
flushAppendOnlyFile函式通過服務器配置appendfsync選項的值來決定的將每次回圈結束之前aof_buf緩沖區的資料寫入到AOF檔案后,將以何種方式同步到AOF檔案里面:
| appendfsync | flushAppendOnlyFile函式的行為 |
|---|---|
always |
每次都同步 |
everysec |
單獨一個執行緒一分鐘同步一次 |
no |
作業系統決定何時同步 |
AOF重寫
AOF方式持久化時記錄的時一條一條的寫命令,隨著服務器運行的時間越來越長,AOF檔案會越來越大,AOF重寫就是為了解決這個問題,
函式aof_rewrite啟動一個子行程創建AOF重寫緩沖區,將Redis中所有的資料生成多條寫命令寫入AOF檔案,在子行程進行AOF重寫期間,服務器還會處理寫請求的命令,這會導致服務器當前的資料庫狀態和重寫后的AOF檔案所保存的資料不一致,為了解決這個問題,子行程在執行AOF重寫期間,服務器行程需要執行以下三件事情:
- 執行客戶端發送來的命令
- 將執行后的寫命令追加到AOF緩沖區
- 將執行后的寫命令追加到AOF重寫緩沖區
當子行程完成AOF重寫作業后,會發送一個信號到父行程,父行程收到信號后會呼叫信號處理函式(這個程序會block主父行程),執行以下作業:
- 將AOF重寫緩沖區中的資料全部寫入到新AOF檔案中,這時新AOF檔案所保存的資料庫狀態和服務器當前的資料庫狀態一致
- 對新的AOF檔案進行改名,原子的覆寫現有的AOF檔案,完成新舊兩個AOF檔案的替換
RDB與AOF區別
- RDB可以理解為是一種全量資料更新機制,AOF可以理解為是一種增量的更新機制,AOF重寫可以理解為是一種全量+增量的更新機制(第一次是全量,后面都是增量)
- RDB適合服務器資料庫資料量小,寫命令頻繁的場景
- AOF適合資料量大,寫命令少的場景
- AOF重寫適合在AOF運行了很久的寫命令之后執行
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/145067.html
標籤:Java
上一篇:Redis中漸進式rehash
下一篇:Redis的事件機制
