【Redis】持久化 rdb和aof

  • redis 提供了兩種方式進行持久化
    • RDB持久化
    • AOF持久化(可以在配置文件中開啓,也可以啓動後開啓)

rdb

rdb 持久化 就是將存儲的數據快照的方式存儲到磁盤上

redis會單獨創建(fork)一個與當前進程一模一樣的子進程來進行持久化(這裏解決的阻塞問題),這個子進程的所有數據(變量。環境變量,程序程序計數器等)都和原進程一模一樣,會先將數據寫入到一個臨時文件中,待持久化結束了,再用這個臨時文件替換上次持久化好的文件,整個過程中,主進程不進行任何的io操作,這就確保了極高的性能.

  • RDB 優勢
    • 一旦採用該方式,那麼你的整個Redis數據庫將只包含一個文件,這樣非常方便進行備份。比如你可能打算每1天歸檔一些數據。
    • 方便備份,我們可以很容易的將一個一個RDB文件移動到其他的存儲介質上
    • RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
    • RDB 可以最大化 Redis 的性能:父進程在保存 RDB 文件時唯一要做的就是 fork 出一個子進程,然後這個子進程就會處理接下來的所有保存工作,父進程無須執行任何磁盤 I/O 操作。
  • RDB劣勢
    • 如果你需要儘量避免在服務器故障時丟失數據,那麼 RDB 不適合你。 雖然 Redis 允許你設置不同的保存點(save point)來控制保存 RDB 文件的頻率, 但是, 因爲RDB 文件需要保存整個數據集的狀態, 所以它並不是一個輕鬆的操作。 因此可能會至少 5 分鐘才保存一次 RDB 文件。 在這種情況下, 一旦發生故障停機就可能會丟失好幾分鐘的數據。
    • 每次保存 RDB 的時候,Redis 都要 fork() 出一個子進程,並由子進程來進行實際的持久化工作。 在數據集比較龐大時, fork() 可能會非常耗時,造成服務器在某某毫秒內停止處理客戶端; 如果數據集非常巨大,並且 CPU 時間非常緊張的話,那麼這種停止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也需要進行 fork() ,但無論 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。

rbd

文件保存過程

  • redis調用fork,現在有了子進程和父進程。
  • 父進程繼續處理client請求,子進程負責將內存內容寫入到臨時文件。由於os的寫時複製機制(copy on write)父子進程會共享相同的物理頁面,當父進程處理寫請求時os會爲父進程要修改的頁面創建副本,而不是寫共享的頁面。所以子進程的地址空間內的數 據是fork時刻整個數據庫的一個快照。
  • 當子進程將快照寫入臨時文件完畢後,用臨時文件替換原來的快照文件,然後子進程退出。

配置

配置文件的SNAPSHOTTING部分就是rdb的相關配置

保存策略

   save 900 1# ((15分鐘)內有1個更改) 則保存

   save 300 10 #((5分鐘)內有10個更)

   save 60 1 #(60秒內有10000個更改)

working directory

放rdb文件的位置
在這裏插入圖片描述
rdb文件名
在這裏插入圖片描述


觸發rdb持久化的機制

  • shutdown的時候 會觸發(前提是沒有開啓aof)

  • 配置文件中的快照

    save 900 1 ((15分鐘)內有1個更改)

    save 300 10((5分鐘)內有10個更)

    save 60 1(60秒內有10000個更改)

  • 執行save (不會fork子進程,使用主程序持久化,所以回阻塞)

  • 執行bgsave(這個會fork 一個子進程)

  • 執行flushall命令 但是裏面是空的,無意義(其實就是生成空的rdb文件)

aof

Append only file
將我們的寫命令都記錄到 appendonly.aof文件中,(通過write函數追加到AOF文件的末尾)
恢復的時候把這些命令都再執行一遍…

  • AOF 優勢
    • 使用 AOF 持久化會讓 Redis 變得非常耐久:你可以設置不同的 fsync 策略,比如無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync 。
    • AOF 文件是一個只進行追加操作的日誌文件, 因此對 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 劣勢
    • 對於相同的數據集來說,AOF 文件的體積通常要大於 RDB 文件的體積。
    • 根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間。

aof 流程

在這裏插入圖片描述

bgrewriteaof命令

  • aof 的方式也同時帶來了另一個問題。持久化文件會變的越來越大。例如我們調用incr test命令100次,文件中必須保存全部的100條命令,其實有99條都是多餘的。因爲要恢復數據庫的狀態其實文件中保存一條set test 100就夠了

    爲了壓縮aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis將使用與快照類似的方式將內存中的數據 以命令的方式保存到臨時文件中,最後替換原來的文件。具體過程如下:

    • redis調用fork ,現在有父子兩個進程
    • 子進程根據內存中的數據庫快照,往臨時文件中寫入重建數據庫狀態的命令
    • 父進程繼續處理client請求,除了把寫命令寫入到原來的aof文件中。同時把收到的寫命令緩存起來。這樣就能保證如果子進程重寫失敗的話並不會出問題。
    • 當子進程把快照內容寫入已命令方式寫到臨時文件中後,子進程發信號通知父進程。然後父進程把緩存的寫命令也寫入到臨時文件。
    • 現在父進程可以使用臨時文件替換老的aof文件,並重命名,後面收到的寫命令也開始往新的aof文件中追加。

配置

配置文件的
APPEND ONLY MODE 部分就是關於aof的配置
在這裏插入圖片描述

持久化策略

在這裏插入圖片描述

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

重寫:自動觸發bgrewriteaof

當AOF文件增長到一定大小的時候Redis能夠調用 bgrewriteaof對日誌文件進行重寫,觸發的條件有以下兩個配置:
在這裏插入圖片描述

auto-aof-rewrite-percentage 100 #當AOF文件大小的增長率大於該配置項時自動開啓重寫(這裏指超過原大小的100%)。
auto-aof-rewrite-min-size 64mb #當AOF文件大小大於該配置項時自動開啓重寫

注意:重寫操作是通過fork子進程來完成的,所以正常的aof不會fork子進程,觸發了重寫纔會

redis4.0後混合持久化機制

混合持久化是通過bgrewriteaof完成的,不同的是當開啓混合持久化時,fork出的子進程先將共享的內存副本全量的以RDB方式寫入aof文件,然後在將重寫緩衝區的增量命令以AOF方式寫入到文件,寫入完成後通知主進程更新統計信息,並將新的含有RDB格式和AOF格式的AOF文件替換舊的的AOF文件。簡單的說:新的AOF文件前半段是RDB格式的全量數據後半段是AOF格式的增量數據。

  • 優點
    • 混合持久化結合了RDB持久化 和 AOF 持久化的優點, 由於絕大部分都是RDB格式,加載速度快,同時結合AOF,增量的數據以AOF方式保存了,數據更少的丟失
  • 缺點
    • 兼容性差,一旦開啓了混合持久化,在4.0之前版本都不識別該aof文件,同時由於前部分是RDB格式,閱讀性較差
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章