1. 程式人生 > 其它 >Redis專題(五)——Redis資料持久化

Redis專題(五)——Redis資料持久化

Redis專題(五)——Redis資料持久化

(原創內容,轉載請註明來源,謝謝)

當伺服器突然發生問題,或者redis重啟,如果希望將資料持久化在硬碟中,下次開啟redis還有資料時,redis提供了兩種方案,一個叫做RDB(通過記憶體快照(Snapshotting)實現),另一個叫做AOF(日誌追加(Append-only file))。通常結合兩種方式來實現redis的持久化。

1、RDB

RDB通過記憶體快照實現,會將redis當前的全部資料以快照的方式寫入二進位制檔案中。實現快照有以下幾種方式:

1)使用者配置規則,自動快照

採用save <seconds><changes>,每當seconds秒內改動超過changes次,則會觸發快照。可以同時設定多個save,每個save是【或】的關係,即滿足一個save就會實現快照。

例如:

         save100 10
         save200 20
         save300 30

表示100秒內改動超過10次,或200秒內改動超過20次,或300秒內改動超過30次,則redis自動快照。

2)手動執行save或bgsave,實現快照

save命令手動執行,會立即快照。但是由於redis的單執行緒特性,則會發生阻塞。且如果redis儲存的內容多,儲存速度較慢。因此不建議save方式實現快照。

bgsave實現在後臺非同步快照,不影響redis的正常使用。

3)flushall命令

flushall會清空redis的所有資料。當執行此命令之前設定過任意快照條件,只要有設定快照觸發條件,flushall命令執行後無論是否滿足快照條件,都很執行一次快照。

4)主從複製

當執行主從複製,即使沒有設定快照條件,也會執行快照操作。

2、快照原理

redis預設將快照儲存在redis當前程序工作目錄中,檔名預設是dump.rdb,可以通過配置dir和dbfilename改變快照的路徑和檔名。快照執行過程如下:

1)redis使用fork函式複製一份當前程序(父程序)的副本(子程序)。fork函式採用寫複製方式,當複製過程中如果有資料改動,會被同步改動到複製後的資料。因此複製的資料是執行fork時間的資料。

2)父程序繼續處理客戶端的命令,子程序將資料寫入硬碟。

3)子程序寫完所有檔案後會將新的RDB替換舊的RDB檔案,寫入完成。

快照的優勢如下:

1)fork可以使得副本複製後,佔用的記憶體不是當前使用量的兩倍,但是仍需要臨時佔用較多記憶體,因此設計的時候需要考慮好用到多少記憶體,避免快照失敗。

2)快照生成的rdb檔案是新的直接替換舊的,因此任意時刻的rdb檔案都是完整的。這也就讓使用者可以定時備份rdb檔案。

3)rdb檔案是壓縮後的檔案,因此實際佔用量小於原來在記憶體的使用量。

3、AOF

AOF開啟後會降低redis異常關閉導致的資料丟失。AOF會將使用者執行的每一條寫命令追加到硬碟中,保證資料實時,此操作會降低效能。

1)開啟AOF

預設情況下是沒開AOF的,可以通過命令appendonlyyes來開啟。開啟後每個寫入的命令都會被執行,預設檔名是appendonly.aof,路徑和rdb相同。

2)AOF詳情

AOF記錄的是redis客戶端給redis傳送的通訊協議原生的內容。

但是,僅記錄命令有可能會浪費空間,如連續10個命令對一個鍵的值進行設定,其實只需要記錄最後一次的操作就可以。redis可以通過配置檔案對aof進行自動重新,包括aof大小超過一定空間,或者本次的檔案內容達到上次重寫後的百分之多少。

另外,可以手動通過命令BGREWRITEAOF,實現手動命令重寫AOF。

AOF採用行的方法記錄,每一行記錄一個內容,要麼是命令,要麼是鍵,要麼是值。因此恢復起來速度比rdb慢。

3)同步硬碟資料

由於作業系統也存在快取,因此每次執行aof的寫入,只是被寫入硬碟的快取中,每30秒會同步到硬碟。因此30秒內如果系統異常奔潰,這30秒的資料可能會丟失。

為了避免這個情況,redis允許配置appendfsync,包括always、no、everysec三種引數。預設是everysec,即每秒強制要作業系統完成一次同步;always每次寫入的時候同步,最安全但最慢;no是用作業系統的方法進行同步,不安全。

通常會同時開啟AOF和RDB兩種持久化,保證資料的一致性。

——written by linhxx 2017.08.10