Redis持久化——問題定位與優化(三)


核心知識點:

1.fork操作

  a.在RDB或AOF重寫時,會執行fork操作創建子進程,fork操作是一個重量級操作。

  b.改善fork操作耗時的手段:避免使用Xen、配置Redis實例最大使用內存、合理配置Liunx內存使用技術、降低fork操作的頻率。

2.子進程開銷監控與優化

  1).CPU

  2).內存

  3).硬盤

3.AOF追加阻塞

 

Redis持久化功能一直是影響Redis性能的高發地,下面我們結合常見的持久化功能問題進行分析定位和優化。

一、fork操作

當Redis做RDB或AOF重寫時,一個必不可少的操作就是執行fork操作創建子進程,對於大多是系統來說fork是一個重量級操作

雖然fork創建的子進程不需要拷貝父進程的物理內存空間,但是會復制父進程的空間內存頁表

例如對於10GB的Redis進程,需要復制大約20MB的內存頁表,因此fork操作耗時跟進程總內存息息相關,

如果使用虛擬化技術,特別是Xen虛擬機,fork操作會更耗時。

 

fork耗時問題定位:對於高流量的Redis實例OPS可達5萬以上,

如果fork操作耗時在秒級別將拖慢Redis幾萬條命令執行,對線上應用延遲影響非常明顯。

正常情況下,fork耗時應該是每GB消耗20毫秒。可以在info stats統計中查latest_fork_usec指標獲取最近一次fork操作耗時,單位微秒。

 

如何改善fork操作的耗時:

1)優先使用物理機或者高效支持fork操作的虛擬機技術,避免使用Xen

2)控制Redis實例最大可用內存,fork耗時跟內存量成正比,線上建議每個Redis實例內存控制在10GB以內。

3)合理配置Linux內存分配策略,避免物理內存不足導致fork失敗。

4)降低fork操作的頻率,如適度放寬AOF自動觸發時機,避免不必要的全量復制等

 

二、子進程開銷監控和優化

子進程負責AOF或者RDB文件的重寫,它的運行過程主要涉及CPU、內存、硬盤三部分的消耗。

1.CPU

(1)CPU開銷分析

子進程負責把進程內的數據分批寫入文件,這個過程屬於CPU密集操作,通常子進程對單核CPU利用率接近90%。

(2)CPU消耗。

Redis是CPU密集型操作,不要做綁定單核CPU的操作。由於子進程非常消耗CPU,會和父進程產生單核資源競爭。

 

不要和其他CPU密集型服務部署在一起,造成CPU過度競爭。

如果部署多個Redis實例,盡量保證同一時刻只有一個子進程執行重寫工作。

 

2.內存

(1)內存消耗分析

子進程通過fork操作產生,占用內存大小等同於父進程,理論上需要兩倍的內存來完成持久化的操作,但是Linux有寫時復制機制。

父進程會共享相同的物理內存頁,當父進程處理寫請求時會把要修改的頁創建副本,而子進程在fork操作過程中共享整個父進程內存快照。

 

(2)內存消耗監控

如果重寫過程中存在內存頁操作,父進程負責創建所修改內存頁的副本,從日志中可以看出這部分的內存消耗。

父進程維護頁副本消耗同RDB重寫過程類似,不同之處在於AOF重寫需要AOF重寫緩沖區。

提示:編寫shell腳本根據Redis日志可快速定位子進程重寫期間內存過度消耗的情況。

 

(3)內存消耗優化

  • 同CPU優化一樣,如果部署多個Redis實例,盡量保證同一時刻只有一個子進程在工作。
  • 避免大量寫入時做子進程重寫操作,這樣將導致父進程維護大量頁副本,造成內存消耗。

在Linux kernel在2.6.38內核增加了Transparent Huge pages(THP),支持huge page(2MB)的頁分配,默認開啟。

當開啟時可以降低fork創建子進程的速度,但執行fork之后,如果開啟HTP,復制頁單位會從原來4KB變為2MB,會大幅增加重寫期間父進程的內存消耗。

 

3.硬盤

(1)硬盤開銷分析

子進程主要職責是把AOF或者RDB文件寫入硬盤持久化,勢必會造成硬盤寫入壓力,

根據Redis重寫AOF/RDB的數據量,結合系統工具如sar、iotop等,可分析出重寫期間硬盤負載情況。

 

(2)硬盤開銷優化

  • 不要和其它高硬盤負載的服務部署在一起。如:存儲服務、消息隊列服務。
  • AOF重寫時會消耗大量硬盤IO,可以開啟配置no-appendfsync-on-rewrite,默認關閉。表示在AOF重寫期間不做fsync操作。
  • 當開啟AOF功能的Redis用於高流量寫入場景時,如果使用普通機械磁盤,寫入吞吐一般在100MB/s左右,這是瓶頸主要在AOF同步硬盤上。
  • 對於單機配置多個Redis實例的情況,可以配置不同實例分盤存儲AOF文件,分攤硬盤寫入壓力。

 

三、AOF追加阻塞

當開啟持久化時,常用的同步硬盤的策略是everysec,用於平衡性能和數據安全性。

對於這種方式,Redis使用另一條線程每秒執行fsync同步硬盤。當系統硬盤資源繁忙時,會造成Redis主線程阻塞。

 

1.阻塞流程分析:

(1)主線程負責寫入AOF緩沖區。

(2)AOF線程負責每秒執行一次同步操作,並記錄最近一次同步時間。

(3)主線程負責每秒執行一次同步磁盤操作,並記錄最近一次同步時間。

  • 如果距上次同步成功時間在2秒內,主線程直接返回。
  • 如果距上次同步時間超過兩秒,主線程將會阻塞,直到同步操作完成。

 

通過分析AOF阻塞流程可以發現兩個問題:

(1)everysec配置最多可能丟失2秒數據,不是1秒。

(2)如果系統fsync緩慢,將會導致Redis主線程阻塞影響效率。

 

2.AOF阻塞問題定位

(1)發生AOF阻塞問題,Redis會在日志中記錄其行為。

(2)每當發生AOF追加阻塞事件,在info Persistence統計中,aof_delayed_fsync指標會累加,查看這個指標方便定位AOF阻塞問題。

(3)AOF同步最多允許2秒延遲,當延遲發生時說明硬盤存在高負載問題,可以通過監控工具如iotop,定位消耗硬盤IO資源的進程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM