Redis持久化的原理及優化

做者:全菜工程師小輝html

連接:https://www.cnblogs.com/mseddl/p/11465417.html?utm_source=tuicool&utm_medium=referrallinux

Redis提供了將數據按期自動持久化至硬盤的能力,包括RDB和AOF兩種方案,兩種方案分別有其長處和短板,能夠配合起來同時運行,確保數據的穩定性。ios

RDB

保存數據快照至一個RDB文件中,用於持久化。RDB操做和Mysql Dump類似。面試

執行方式

  • save。同步操做,會阻塞Redis。
  • bgsave。調用linux的fork(),而後使用新的線程執行復制。可是fork期間也會阻塞Redis,可是阻塞時間一般很短。
  • 自動保存。Redis配置文件中設置了自動保存的觸發機制,能夠自定義修改,運行原理同bgsave。

save和bgsave的對比

注意:sql

  • 若是機器上運行多個Redis,須要配置RDB文件名稱,不然多個Redis的RDB文件會相互覆蓋。

除了上述三種執行方式,如下狀況也會生成RDB文件:數據庫

  • 主從的全量複製時,主機會生成RDB文件。
  • Redis中的debug reload提供debug級別的重啓,不清空內存的一種重啓,這種方式也會觸發RDB文件的生成。
  • 執行shutdown時,會觸發RDB文件的生成。

RDB的缺點

  • 全量數據存儲,耗時。
  • 雖然fork()採用copy-on-write策略,但仍消耗內存
  • 寫RDB文件消耗大量IO性能。

AOF

採用AOF持久方式時,Redis會把每個寫請求都記錄在一個日誌文件裏,AOF操做和Mysql Binlog類似。經過AOF重寫機制減小AOF文件的體積,從而減小恢復時間。bash

執行方式

  • always。Redis的每條寫命令都寫入到系統緩衝區,而後每條寫命令都使用fsync「寫入」硬盤。
  • everysec。過程與always相同,只是fsync的頻率爲1秒鐘一次。這個是Redis默認配置,若是系統宕機,會丟失一秒左右的數據
  • no。由操做系統決定何時從系統緩衝區刷新到硬盤。

AOF重寫

爲了解決AOF文件體積膨脹的問題,Redis提供了AOF重寫功能:Redis服務器能夠建立一個新的AOF文件來替代現有的AOF文件,新舊兩個文件所保存的數據庫狀態是相同的,可是新的AOF文件不會包含任何浪費空間的冗餘命令,一般體積會較舊AOF文件小不少。服務器

AOF重寫方式

  • bgrewriteaof(流程與bgsave類似)
  • AOF重寫配置(與RDB自動保存類似)

AOF重寫並不須要對原有AOF文件進行任何的讀取,寫入,分析等操做,這個功能是經過讀取服務器當前的數據庫狀態來實現的。微信

RDB vs AOF

Redis啓動時的數據加載

Redis啓動數據加載流程:架構

  1. AOF持久化開啓且存在AOF文件時,優先加載AOF文件。
  2. AOF關閉或者AOF文件不存在時,加載RDB文件。
  3. 加載AOF/RDB文件成功後,Redis啓動成功。
  4. AOF/RDB文件存在錯誤時,Redis啓動失敗並打印錯誤信息。

開發運維中常見的問題

fork操做

fork()的實際開銷就是複製父進程的頁表以及給子進程建立一個進程描述符,因此速度通常比較快

內存量越大,耗時越長;物理機相對較快,虛擬機相對較慢。

優化方法

  1. 優先使用物理機或者高效支持fork操做的虛擬化技術
  2. 控制Redis實例最大可用內存maxmemory
  3. 合理配置Linux內存分配策略:vm.overcommit_memory=1。默認值爲0,會使Linux在內存分配時,發現不夠內存不足時,不會進行分配,進而形成fork阻塞,加微信號 weixin99ting 免費領取(BATJ面試資料、高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)和Java進階學習路線圖)
  4. 下降fork頻率。例如放寬AOF重寫自動觸發時機或者減小沒必要要的主從全量複製

進程外開銷

  • CPU。RDB和AOF文件生成,屬於CPU密集型。不要將Redis進程綁定在某個CPU上,防止單核過載;同時Redis不和CPU密集型應用一塊兒部署。
  • 內存。fork內存開銷,copy-on-write。
  • 硬盤。AOF和RDB文件的寫入。能夠結合iostat和iotop進行分析。

優化方法

  1. 不要和高硬盤負載服務部署在一塊兒:存儲服務、消息隊列等
  2. 配置no-appendfsync-on-rewrite=yes。這樣在AOF重寫的期間,不要進行AOF追加操做(主線程只將數據寫入緩衝區),能夠減小內存的開銷。

但若是AOF重寫期間,Redis宕機的話,在Linux的系統默認配置下,最多會丟失30s的數據。若是沒法忍受數據丟失,no-appendfsync-on-rewrite配置no;若是應用系統沒法忍受延遲,而能夠容忍少許的數據丟失,則設置爲yes。

  1. 根據寫入量決定磁盤類型:例如ssd
  2. 單機多實例持久化文件目錄能夠考慮分盤,或者使用相似cgroups機制進行硬盤資源的合理分配

AOF追加阻塞

例如在AOF的everysec策略中,主線程會對比上次fsync的時間,若是距離上次fsync時間超過兩秒,就會形成主線程阻塞(等待同步線程同步完成)。

平常開發可使用 info persistence 命令,查看歷史發生AOF阻塞的次數;然而須要瞭解AOF追加阻塞的發生時間則須要查看Redis日誌。

發送AOF追加阻塞的時候,日誌以下:

Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.複製代碼

優化方法(參考其餘方面的優化點)

相關文章
相關標籤/搜索