redis-持久化

持久化即備份,這是單機高可用的策略之一,有了備份,就能夠在Redis故障經過備份進行恢復。redis持久化主要有RDB和AOF。linux

  1. RDBredis

    RDB(Redis DataBase),基於策略定時將redis內存中的數據保存到硬盤。須要時能夠經過這個備份文件進行恢復。安全

  2. AOF服務器

    AOF(Append Only File),是把每次redis執行的命令記錄到日誌文件中(相似於MySql的Bin log),當Redis啓動時能夠經過執行log中的命令來恢復數據app

1、RDB

1.1 觸發機制

save命令:阻塞當前redis服務器,直到RDB過程完成,服務器在阻塞期間不能處理如何客戶端請求,原則上save命令已經廢棄。函數

bgsave命令:會fork一個子進程,RDB的持久化由這個子進程來完成,阻塞只發生在fork階段,耗時較短,子進程執行rdb期間redis服務器不會阻塞,正常處理客戶端請求。性能

自動觸發機制:在redis.conf 配置:操作系統

save m n

表明若是在m秒內存在n次的修改時,則執行bgsave命令線程

1.2 流程說明

  1. 執行bgsave命令,redis父進程判斷若是當前存在正在執行的子進程,則直接返回,好比AOF或者RDB子進程。
  2. 父進程fork一個子進程,fork過程父進程是阻塞,沒法響應客戶端請求
  3. fork結束後,bgsave返回「background saving started」信息,而且再也不阻塞父進程,父進程能夠繼續響應客戶端請求。
  4. 子進程根據父進程的內存快照建立RDB文件,完成後對原有文件進行原子替換。
  5. 子進程發送信號給父進程表示RDB完成

1.3 RDB優缺點

優勢日誌

  1. RDB是一個壓縮的二進制文件,表明Redis在某個時間點上的數據快照,適合備份,全量複製等場景
  2. Redis加載RDB恢復數據遠遠快於AOF

缺點

  1. RDB沒法作到實時持久化
  2. 兼容性問題,新版本的redis可能沒法兼容老版本的RDB

爲了解決實時持久化問題,redis引入了AOF。

2、AOF

2.1 開啓AOF

AOF默認是關閉的,經過以下命令開啓:

appendonly yes

2.2 AOF流程

AOF工做基本流程:

  1. 命令寫入(append):redis全部的寫入命令會追加到aof_buf(緩衝區)中
  2. 文件同步(sync):AOF緩衝區根據對應的策略向硬盤作同步操做
  3. 文件重寫(rewrite):隨着AOF文件愈來愈大,須要按期對AOF文件進行重寫,達到壓縮的目的
  4. 重啓加載(load):redis啓動後能夠加載AOF文件進行數據恢復。

命令寫入

對於每一條redis寫入命令,在AOF中會追加一條文本,文本格式是redis文本協議格式(RESP),直接採用協議格式,以來兼容性和可讀性高,二來避免了二次處理的開銷。

若是直接把命令寫入硬盤會影響到redis的性能。先寫入aof_buf,而後後期經過同步策略寫入硬盤,避免直接的IO影響到redis的性能。

文件同步

redis提供了多種AOF緩衝區文件同步策略,同步策略分別使用了操做系統的wirte函數和fsync函數,說明以下:

write: 會觸發延遲寫(delayed write)操做,爲了性能,linux在內核提供了頁緩衝區用來提升硬盤的IO性能,write操做在寫入系統緩衝區後直接返回,後期同步硬盤操做依賴於操做系統調度(好比按時,或者緩衝區慢等)。若是在同步前出現系統宕機故障,緩衝區的數據會丟失。

fsync: 強制操做系統將緩衝區的操做同步到硬盤。

由appendfsync參數控制:

可配置的值 說明
always 命令寫入buf後調用系統調用fsync同步AOF文件,fsync完成後線程返回
no 命令寫入buf後調用系統調用write操做,後續fsync同步操做由操做系統來完成,通常爲30秒一次。
everysec 命令寫入buf後調用系統調用write操做,後續fsync同步操做專門線程每一秒調用一次。

everysec是always和no的折中,是性能和安全性的這種,是redis默認的配置,也是比較推薦的配置。

文件重寫

文件重寫就是把Redis進程裏面的最新數據轉化爲寫命令而後同步到aof文件的過程,經過重寫不但能夠減少aof文件的體積,從而進一步提升aof文件在恢復過程當中的加載速度。

由如下緣由能夠經過aof重寫減小aof文件的體積:

  1. 舊的apf包含過時的數據再也不寫入aof,好比 set k1 aaa,這條命令已通過期,可是已經在aof文件中存在,經過重寫這條命令將移除aof文件。
  2. 舊的aof中存在無效的命令,好比set k1 111,set k1 222,aof中存在兩條命令,其實第一條已經失效,經過重寫,能夠變成一條。
  3. 多條命令命令合併。

觸發機制:

  1. 手動觸發:執行bgrewriteaof命令

  2. 自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數肯定自動觸發時機:

    • auto-aof-rewrite-min-size:表示運行aof重寫時文件的最小體積,默認爲64MB

    • auto-aof-rewrite-percentage:表示當前aof文件的size(aof_current_size)和上一次重寫後aof文件的size(aof_base_size)的比值。

      只有當以上兩個條件同時知足時,纔會觸發自動aof

aof重寫流程:

  1. 執行aof重寫請求
  2. 父進程fork一個子進程,開銷等同於bgsave時候fork的過程
  3. aof緩衝區寫入
    1. fork結束後,主進程繼續響應客戶端請求,全部修改命令都會寫入aof_buf,後續基於appendfsync策略寫入硬盤
    2. 因爲fork操做運用寫時複製技術,子進程只能共享fork操做時的的內存數據。在執行bgrewrite期間,主進程依然在響應命令,redis用aof_rewrite_buf來保存這部分數據,防止在新的aof文件生成期間丟失這部分數據。
  4. 寫入新的AOF,子進程基於fork後的aof_buf(快照)生成新的aof文件
  5. 後續操做
    1. 子進程發送信號通知父進程aof生成完成,父進程更新相關統計信息
    2. 父進程把aof_rewrite_buf的數據寫入到新的aof文件
    3. 使用最新的aof文件替換老文件,完成最終的AOF重寫。

3、重啓加載流程

  1. 優先加載AOF
  2. AOF關閉時加載RDB
  3. 加載成功後redis才能成功啓動
  4. 加載失敗,則redis啓動失敗
相關文章
相關標籤/搜索