Redis 持久化

Redis提供了兩種持久化方式:

  • RDB (Redis DataBase)
    在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)

  • AOP(Append Only File)
    記錄服務器執行的所有寫操作命令,並在服務器啓動時,通過重新執行這些命令來還原數據集。

Redis 還可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重啓時, 它會優先使用 AOF 文件來還原數據集, 因爲 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整。

RDB

Redis 會單獨的創建(fork) 一個子進程來進行持久化,會先將數據寫入到一個臨時文件中,待持久化過程結束了,再用這個臨時文件替換上次持久化還的文件。
整個過程中,主進程是不進行任何 IO 操作,這就確保了極高的性能,如果需要進行大規模的數據恢復,且對於數據恢復的完整性不是非常敏感,那 RDB 方法要比 AOF 方式更加的高效。
RDB 的缺點是最後一次持久化後的數據可能丟失。若當前的進程的數據量龐大,那麼 fork 之後數據量*2,此時就會造成服務器壓力大,運行性能降低。
fork 的作用是複製一個與當前進程一樣的進程,新進程的所有數據(變量、環境變量、程序計數器等)數值都和原進程一致,但是是一個全新的進程,並作爲原進程的子進程。之所以不使用線程而選擇fork子進程,是利用了fork複製進程資源的特性,將redis當前狀態拷貝一份,再持久化到文件中。而線程的做法就會破壞redis的單線程讀寫模型,造成對數據的競爭。

執行:

  • 開啓配置:

    save 900 1     
    #900秒內如果超過1個key被修改,則發起快照保存
    
    save 300 10    
    #300秒內容如超過10個key被修改,則發起快照保存
    
    save 60 10000
    #60秒內容如超過10000個key被修改,則發起快照保存
    
  • 命令執行:
    SAVE 直接調用rdbSave,阻塞Redis主進程看,直到保存完成爲止。在主進程阻塞期間,服務器不能處理客戶端的任何請求。
    BGSAVE 則fork 出一個子進程,子進程負責調用rdbSave ,並在保存完成之後向主進程發送信號,通知保存已完成。因爲rdbSave 在子進程被調用,所以Redis 服務器在BGSAVE 執行期間仍然可以繼續處理客戶端的請求。

AOP

AOF 則以協議文本的方式,將所有對數據庫進行過寫入的命令(及其參數)記錄到AOF文件,以此達到記錄數據庫狀態的目的。AOF文件其實可以認爲是Redis寫操作的日誌記錄文件。

開啓配置:

appendonly yes              //啓用aof持久化方式
# appendfsync always      //每次收到寫命令就立即強制寫入磁盤,最慢的,但是保證完全的持久化,不推薦使用
appendfsync everysec     //每秒鐘強制寫入磁盤一次,在性能和持久化方面做了很好的折中,推薦
# appendfsync no    //完全依賴os,性能最好,持久化沒保證

Rewrite
AOF 採用文件追加方式,文件會越來越來大。爲避免出現此種情況,新增了重寫機制:當aof 文件的大小超過所設定的閾值時,redis 就會自動 aof 文件的內容壓縮,值保留可以恢復數據的最小指令集,可以使用命令bgrewirteaof。
重寫原理:aof 文件持續增長而大時,會fork出一條新進程來將文件重寫(也就是先寫臨時文件最後再rename)。重寫aof文件時並沒有讀取原來的文件,而是遍歷新進程的內存中的數據,將其作爲寫命令追加到文件,這點和快照有點類似。
觸發機制:redis 會記錄上次重寫的 aof 的大小,默認的配置當 aof 文件大小上次 rewrite 後大小的一倍且文件大於 64M 觸發

no-appendfsync-on-rewrite no
# 重寫時是否可以運用 Appendfsync 用默認no即可,保證數據安全
auto-aof-rewrite-percentage 100
# 重寫觸發的倍數
auto-aof-rewrite-min-size 64mb
# 設置基準值大小

優勢
AOP的優勢在於使得Redis變得非常可靠:你可以設置不同的 fsync 策略,比如無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync 。 AOF 的默認策略爲每秒鐘 fsync 一次,在這種配置下,Redis 仍然可以保持良好的性能,並且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync 會在後臺線程執行,所以主線程可以繼續努力地處理命令請求)

AOF 文件是一個只進行追加操作的日誌文件(append only log), 因此對 AOF 文件的寫入不需要進行 seek , 即使日誌因爲某些原因而包含了未寫入完整的命令(比如寫入時磁盤已滿,寫入中途停機,等等), redis-check-aof 工具也可以輕易地修復這種問題。

Redis 可以在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操作是絕對安全的,因爲 Redis 在創建新 AOF 文件的過程中,會繼續將命令追加到現有的 AOF 文件裏面,即使重寫過程中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。

AOF 文件有序地保存了對數據庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式保存, 因此 AOF 文件的內容非常容易被人讀懂, 對文件進行分析(parse)也很輕鬆。 導出(export) AOF 文件也非常簡單: 舉個例子, 如果你不小心執行了 FLUSHALL 命令, 但只要 AOF 文件未被重寫, 那麼只要停止服務器, 移除 AOF 文件末尾的 FLUSHALL 命令, 並重啓 Redis , 就可以將數據集恢復到 FLUSHALL 執行之前的狀態。

缺點

對於相同的數據集來說,AOF 文件的體積通常要大於 RDB 文件的體積。

根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章