RDB的原理:服務器
在Redis中RDB持久化的觸發分爲兩種:本身手動觸發與Redis定時觸發。併發
針對RDB方式的持久化,手動觸發可使用:app
1):save:會阻塞當前Redis服務器,直到持久化完成,線上應該禁止使用。運維
2):bgsave:該觸發方式會fork一個子進程,由子進程負責持久化過程,所以阻塞只會發生在fork子進程的時候。性能
而自動觸發的場景主要是有如下幾點:spa
1):根據咱們的 save m n
配置規則自動觸發;debug
2):從節點全量複製時,主節點發送rdb文件給從節點完成複製操做,主節點會觸發 bgsave
;code
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。