redis++:Redis持久化 rdb & aof 工做原理及流程圖 (三)

RDB的原理:服務器

在Redis中RDB持久化的觸發分爲兩種:本身手動觸發與Redis定時觸發。併發

針對RDB方式的持久化,手動觸發可使用:app

  1):save:會阻塞當前Redis服務器,直到持久化完成,線上應該禁止使用。運維

  2):bgsave:該觸發方式會fork一個子進程,由子進程負責持久化過程,所以阻塞只會發生在fork子進程的時候。性能

而自動觸發的場景主要是有如下幾點:spa

  1):根據咱們的 save m n 配置規則自動觸發;debug

  2):從節點全量複製時,主節點發送rdb文件給從節點完成複製操做,主節點會觸發 bgsavecode

  3):執行 debug reload 時;blog

  4):執行 shutdown時,若是沒有開啓aof,也會觸發。進程

因爲 save 基本不會被使用到,咱們重點看看 bgsave 這個命令是如何完成RDB的持久化的。流程圖以下

一、Redis父進程首先判斷:當前是否在執行save,或bgsave/bgrewriteaof(aof文件重寫命令)的子進程,若是在執行則bgsave命令直接返回。

      bgsave/bgrewriteaof 的子進程不能同時執行,主要是基於性能方面的考慮:兩個併發的子進程同時執行大量的磁盤寫操做,可能引發嚴重的性能問題。

二、父進程執行fork操做建立子進程,這個過程當中父進程是阻塞的,Redis不能執行來自客戶端的任何命令;

三、父進程fork後,bgsave命令返回」Background saving started」信息並再也不阻塞父進程,並能夠響應其餘命令;

四、子進程建立RDB文件,根據父進程內存快照生成臨時快照文件,完成後對原有文件進行原子替換;

五、子進程發送信號給父進程表示完成,父進程更新統計信息。

 

AOF的原理:

  AOF的整個流程大致來看能夠分爲兩步,一步是命令的實時寫入(若是是 appendfsync everysec 配置,會有1s損耗),第二步是對aof文件的重寫。

  對於增量追加到文件這一步主要的流程是:命令寫入=》追加到aof_buf =》同步到aof磁盤。

  那麼這裏爲何要先寫入buf在同步到磁盤呢?若是實時寫入磁盤會帶來很是高的磁盤IO,影響總體性能。

  aof重寫是爲了減小aof文件的大小,能夠手動或者自動觸發,關於自動觸發的規則請看上面配置部分。

  fork的操做也是發生在重寫這一步,也是這裏會對主進程產生阻塞。

  手動觸發: bgrewriteaof,自動觸發 就是根據配置規則來觸發,固然自動觸發的總體時間還跟Redis的定時任務頻率有關係。

流程圖以下:

 

對於上圖有四個關鍵點補充一下:

一、在重寫期間,因爲主進程依然在響應命令,爲了保證最終備份的完整性;所以它依然會寫入舊的AOF file中,若是重寫失敗,可以保證數據不丟失。

二、爲了把重寫期間響應的寫入信息也寫入到新的文件中,所以也會爲子進程保留一個buf,防止新寫的file丟失數據。

三、重寫是直接把當前內存的數據生成對應命令,並不須要讀取老的AOF文件進行分析、命令合併。

四、AOF文件直接採用的文本協議,主要是兼容性好、追加方便、可讀性高可認爲修改修復。

不管是 RDB 仍是 AOF 都是先寫入一個臨時文件,而後經過 rename 完成文件的替換工做。

 

持久化中恢復數據:

  數據的備份、持久化作完了,咱們如何從這些持久化文件中恢復數據呢?若是一臺服務器上有既有RDB文件,又有AOF文件,該加載誰呢?

  其實想要從這些文件中恢復數據,只須要從新啓動Redis便可。

恢復數據流程圖:

 

啓動時會先檢查AOF文件是否存在,若是不存在就嘗試加載RDB。

那麼爲何會優先加載AOF呢?由於AOF保存的數據更完整,經過上面的分析咱們知道AOF基本上最多損失1s的數據。

 

性能與實踐:

經過上面的分析,咱們都知道RDB的快照、AOF的重寫都須要fork,這是一個重量級操做,會對Redis形成阻塞。所以爲了避免影響Redis主進程響應,咱們須要儘量下降阻塞。

一、下降fork的頻率,好比能夠手動來觸發RDB生成快照、與AOF重寫;

二、控制Redis最大使用內存,防止fork耗時過長;

三、使用更牛逼的硬件;

四、合理配置Linux的內存分配策略,避免由於物理內存不足致使fork失敗。

在線上咱們到底該怎麼作?我提供一些本身的實踐經驗。

一、若是Redis中的數據並非特別敏感或者能夠經過其它方式重寫生成數據,能夠關閉持久化,若是丟失數據能夠經過其它途徑補回;

二、本身制定策略按期檢查Redis的狀況,而後能夠手動觸發備份、重寫數據;

三、單機若是部署多個實例,要防止多個機器同時運行持久化、重寫操做,防止出現內存、CPU、IO資源競爭,讓持久化變爲串行;

四、能夠加入主從機器,利用一臺從機器進行備份處理,其它機器正常響應客戶端的命令;

五、RDB持久化與AOF持久化能夠同時存在,配合使用。

本文的內容主要是運維上的一些注意點,但咱們開發者瞭解到這些知識,在某些時候有助於咱們發現詭異的bug。

相關文章
相關標籤/搜索