Redis學習筆記(11)- Redis的持久化

1、簡介

  Redis是一個內存數據庫,所以數據全部存在內存中,如何保證Redis在突然宕機後,數據還可以進行恢復,這就需要Redis提供的持久化機制來實現。Redis持久化機制提供了兩種方式:一種快照(RDB ),一種AOF日誌。下面將分別學習兩種持久化機制的相關內容。

2、快照(RDB)

  快照是一種全量的持久化機制,即把當前內存中的全部數據集的快照寫入磁盤中,恢復時再將快照文件直接讀到內存裏。快照時內存數據的二進制序列化形式,在存儲上非常緊湊,所以和AOF日誌方式相比,這種方法的文件體積更小。
  Redis提供的快照(RDB)機制,提供自動觸發(即通過Redis.conf配置)和手動配置(Redis命令)兩種方式。下面首先學習自動觸發的方式。

2.1、RDB自動觸發
  1. save配置
    在這裏插入圖片描述
    save: 用來配置觸發 Redis的 RDB 持久化條件,格式:“save m n”,表示m秒內數據集存在n次修改時,自動觸發持久化,本質上和執行了bgsave命令類似。多個save時,滿足一個條件即可觸發該操作。如果不需要持久化,可以註釋掉所有的 save 行或者save “”實現停用。
      如果在後臺持久化的過程中,出現錯誤時,Redis的write操作會報錯,用來提醒用戶當前持久化出現問題,避免出現災難性問題。如果後臺持久化功能恢復,Redis的write操作就會自動恢復。(其實就是上面截圖中的解釋)
  2. stop-writes-on-bgsave-error
    在這裏插入圖片描述
    stop-writes-on-bgsave-error: 默認yes。yes表示啓用了RDB且最後一次後臺保存數據失敗,Redis是否停止write操作。
  3. rdbcompression
    在這裏插入圖片描述
    rdbcompression: 默認yes。表示使用LZF壓縮dump.rdb文件。如果考慮節省CPU資源,可以設置爲no,這個時候dump.rdb文件會比較大。
  4. rdbchecksum
    在這裏插入圖片描述
    rdbchecksum: 默認值是yes。在存儲快照後,我們還可以讓redis使用CRC64算法來進行數據校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能。
  5. dbfilename、dir
    在這裏插入圖片描述
    dbfilename: 快照的文件名,默認是 dump.rdb。
    dir: 快照文件的存放路徑,該配置項一定是個目錄,而不能是文件名。默認是和當前配置文件保存在同一目錄。
2.2、RDB手動觸發

  Redis手動觸發RDB的命令有兩個:save和bgsave。

  1. save命令
      該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成爲止。
      一般來說,在生產環境很少執行 SAVE 操作,因爲它會阻塞所有客戶端,保存數據庫的任務通常由 BGSAVE 命令異步地執行。然而,如果負責保存數據的後臺子進程不幸出現問題時, SAVE 可以作爲保存數據的最後手段來使用。
  2. bgsave命令
      執行該命令時,Redis會在後臺異步進行快照操作,快照同時還可以響應客戶端請求。具體操作是Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。

參考: 《Redis命令參考- -持久化》

2.3、RDB實現原理

  Redis使用操作系統的多進程COW(Copy On Write)機制來實現快照的持久化。Redis在持久化時,會調用函數fork產生一個子進程,快照持久化完全交給子進程進行處理,父進程繼續處理客戶端請求。子進程剛創建時,子進程和父進程共享內存中的代碼和數據。在後續過程中,子進程做數據持久化過程中,不會修改現有數據結構,它只是遍歷數據,並序列化到磁盤中,而父進程在處理客戶端請求時,會修改數據結構,這個時候就用到了操作系統的多進程COW。
  操作系統的多進程COW, 即寫入時複製(Copy-on-write,簡稱COW),是一種計算機程序設計領域的優化策略。其核心思想是,如果有多個調用者(callers)同時要求相同資源(如內存或磁盤上的數據存儲),他們會共同獲取相同的指針指向相同的資源,直到某個調用者試圖修改資源的內容時,系統纔會真正複製一份專用副本(private copy)給該調用者,而其他調用者所見到的最初的資源仍然保持不變。這過程對其他的調用者都是透明的(transparently)。此作法主要的優點是如果調用者沒有修改該資源,就不會有副本(private copy)被創建,因此多個調用者只是讀取操作時可以共享同一份資源。

參考:《不會產奶的COW(Copy-On-Write)》

3、AOF日誌

  AOF持久化機制是一種連續增量備份,AOF日誌記錄的是內存數據修改的指令記錄文本,類似MySQL的binlog。AOF日誌,在長時間運行的過程中會變得非常龐大,Redis重啓時需要加載AOF日誌進行指令重放。

3.1、開啓AOF日誌的方式

  默認情況下,AOF日誌是沒有開啓的。可以通過修改redis.conf配置文件,進行啓用AOF持久化功能。
  首先,修改appendonly參數,設置爲yes。
在這裏插入圖片描述
  Redis默認提供的是RDB持久化方案。該方法可以滿足大部分情況,但是可能造成最近寫入且未保存到快照中的那些數據丟失。
  AOF持久化提供了另外一種形式的備份。AOF持久化可以根據appendfsync的配置選擇進行增量備份命令的策略,Redis默認使用的是每秒記錄一次(平衡備份次數和性能)。
  AOF和RDB持久化可以同時使用。如果AOF持久化被啓用,Redis會在啓動的時候重放AOF文件中記錄的命令,因爲這個過程相對比較慢,所有需要定期對AOF文件進行重寫,用來保證AOF文件比較小。

  其次,修改appendfilename參數,用了設置AOF日誌的文件名。
在這裏插入圖片描述
  最後,配置appendfsync,設置redis多久纔將命令持久化到磁盤一次。
在這裏插入圖片描述

  • appendfsync always:每次有新命令追加到aof文件時就執行一個持久化,非常慢但是安全
  • appendfsync everysec:每秒執行一次持久化,足夠快(和使用rdb持久化差不多)並且在故障時只會丟失1秒鐘的數據
  • appendfsync no:從不持久化,將數據交給操作系統來處理。redis處理命令速度加快但是不安全。
3.2、AOF日誌的重寫

  AOF文件裏可能有太多“瑣碎”指令,所以AOF會定期根據內存的最新數據重新生成AOF文件。AOF觸發重寫的方式有兩種:自動觸發(redis.conf配置)和手動觸發(命令行觸發),下面分別介紹:

  1. 自動觸發
    Redis自動觸發重新AOF日誌的配置,如下所示:
    在這裏插入圖片描述
    首先,no-appendfsync-on-rewrite參數用來啓用自動重寫功能。重寫操作觸發時機,由auto-aof-rewrite-percentage和auto-aof-rewrite-min-size兩個參數控制。其中,auto-aof-rewrite-percentage用來設置AOF文件增長比例,指當前AOF文件比上次重寫的增長比例達到多少時,觸發重寫操作;auto-aof-rewrite-min-size則表示AOF文件重寫的最小的文件大小,即最開始AOF文件必須要達到這個文件時才觸發,後面的每次重寫就根據上一次重寫完成之後的大小進行觸發了,主要用於第一次重寫時。

  2. 手動觸發
    通過BGREWRITEAOF命令,可以實現手動觸發AOF重寫操作。執行一個 AOF文件 重寫操作。重寫會創建一個當前 AOF 文件的體積優化版本。即使 BGREWRITEAOF 執行失敗,也不會有任何數據丟失,因爲舊的 AOF 文件在 BGREWRITEAOF 成功之前不會被修改。

  重寫操作只會在沒有其他持久化工作在後臺執行時被觸發,也就是說:

  • 如果 Redis 的子進程正在執行快照的保存工作,那麼 AOF 重寫的操作會被預定(scheduled),等到保存工作完成之後再執行 AOF 重寫。在這種情況下, BGREWRITEAOF 的返回值仍然是 OK ,但還會加上一條額外的信息,說明 BGREWRITEAOF 要等到保存操作完成之後才能執行。在 Redis 2.6 或以上的版本,可以使用 INFO [section] 命令查看 BGREWRITEAOF 是否被預定。

  • 如果已經有別的 AOF 文件重寫在執行,那麼 BGREWRITEAOF 返回一個錯誤,並且這個新的 BGREWRITEAOF 請求也不會被預定到下次執行。

參考: 《Redis命令參考- -持久化》

3.3、AOF日誌的恢復

  如果AOF日誌功能開啓了,每次啓動Redis的時候,就會恢復AOF文件,這個時候會涉及到一個參數:aof-load-truncated。如下所示:
在這裏插入圖片描述
  指Redis在恢復時,會忽略最後一條可能存在問題的指令。默認值yes。即在AOF寫入時,可能存在指令寫錯的問題(突然斷電,寫了一半),這種情況下,yes會繼續,而no會直接恢復失敗。

4、RDB和AOF持久化方案的對比

在這裏插入圖片描述

5、Redis混合持久化

  混合持久化是Redis 4.X之後的一個新特性,其實本質上就是一種RDB&AOF的結合,持久化文件變成了RDB + AOF。首先由RDB定期完成內存快照的備份,然後再由AOF完成兩次RDB之間的數據備份。這樣就充分了利用了RDB 加載快,備份文件小等特點,也利用了AOF能儘可能不丟數據這個特性(進一步保證了數據一致性),當然了基本上丟失了AOF的可讀性。加載過程就是按部分進行加載的,先按照RDB進行加載,然後把AOF命令追加寫入就好了。在大多數場景下RDB + AOF的混合持久化模式其實還是很合適的。
在這裏插入圖片描述

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