当前位置:网站首页>Redis入門完整教程:問題定比特與優化
Redis入門完整教程:問題定比特與優化
2022-07-07 02:47:00 【穀哥學術】
Redis持久化功能一直是影響Redis性能的高發地,本節我們結合常見的
持久化問題進行分析定比特和優化。
5.3.1 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失敗,具
體細節見12.1節“Linux配置優化”。
4)降低fork操作的頻率,如適度放寬AOF自動觸發時機,避免不必要
的全量複制等。
5.3.2 子進程開銷監控和優化
子進程負責AOF或者RDB文件的重寫,它的運行過程主要涉及CPU、內
存、硬盤三部分的消耗。
1.CPU
·CPU開銷分析。子進程負責把進程內的數據分批寫入文件,這個過程
屬於CPU密集操作,通常子進程對單核CPU利用率接近90%.
·CPU消耗優化。Redis是CPU密集型服務,不要做綁定單核CPU操作。
由於子進程非常消耗CPU,會和父進程產生單核資源競爭。
不要和其他CPU密集型服務部署在一起,造成CPU過度競爭。
如果部署多個Redis實例,盡量保證同一時刻只有一個子進程執行重寫
工作,具體細節見5.4節多實例部署”。
2.內存
·內存消耗分析。子進程通過fork操作產生,占用內存大小等同於父進
程,理論上需要兩倍的內存來完成持久化操作,但Linux有寫時複制機制
(copy-on-write)。父子進程會共享相同的物理內存頁,當父進程處理寫請
求時會把要修改的頁創建副本,而子進程在fork操作過程中共享整個父進程
內存快照。
·內存消耗監控。RDB重寫時,Redis日志輸出容如下:
* Background saving started by pid 7692
* DB saved on disk
* RDB: 5 MB of memory used by copy-on-write
* Background saving terminated with success
如果重寫過程中存在內存修改操作,父進程負責創建所修改內存頁的副
本,從日志中可以看出這部分內存消耗了5MB,可以等價認為RDB重寫消耗
了5MB的內存。
AOF重寫時,Redis日志輸出容如下:
* Background append only file rewriting started by pid 8937
* AOF rewrite child asks to stop sending diffs.
* Parent agreed to stop sending diffs. Finalizing AOF...
* Concatenating 0.00 MB of AOF diff received from parent.
* SYNC append only file rewrite performed
* AOF rewrite: 53 MB of memory used by copy-on-write
* Background AOF rewrite terminated with success
* Residual parent diff successfully flushed to the rewritten AOF (1.49 MB)
* Background AOF rewrite finished successfully
父進程維護頁副本消耗同RDB重寫過程類似,不同之處在於AOF重寫需
要AOF重寫緩沖區,因此根據以上日志可以預估內存消耗為:
53MB+1.49MB,也就是AOF重寫時子進程消耗的內存量。
運維提示
編寫shell脚本根據Redis日志可快速定比特子進程重寫期間內存過度消耗
情况。
內存消耗優化:
1)同CPU優化一樣,如果部署多個Redis實例,盡量保證同一時刻只有
一個子進程在工作。
2)避免在大量寫入時做子進程重寫操作,這樣將導致父進程維護大量
頁副本,造成內存消耗。
Linux kernel在2.6.38內核增加了Transparent Huge Pages(THP),支持
huge page(2MB)的頁分配,默認開啟。當開啟時可以降低fork創建子進程
的速度,但執行fork之後,如果開啟THP,複制頁單比特從原來4KB變為
2MB,會大幅增加重寫期間父進程內存消耗。建議設置“sudo echo
never>/sys/kernel/mm/transparent_hugepage/enabled”關閉THP。更多THP細節
和配置見12.1節Linux配置優化”。
3.硬盤
·硬盤開銷分析。子進程主要職責是把AOF或者RDB文件寫入硬盤持久
化。勢必造成硬盤寫入壓力。根據Redis重寫AOF/RDB的數據量,結合系統
工具如sar、iostat、iotop等,可分析出重寫期間硬盤負載情况。
·硬盤開銷優化。優化方法如下:
a)不要和其他高硬盤負載的服務部署在一起。如:存儲服務、消息隊
列服務等。
b)AOF重寫時會消耗大量硬盤IO,可以開啟配置no-appendfsync-on-
rewrite,默認關閉。錶示在AOF重寫期間不做fsync操作。
c)當開啟AOF功能的Redis用於高流量寫入場景時,如果使用普通機械
磁盤,寫入吞吐一般在100MB/s左右,這時Redis實例的瓶頸主要在AOF同步
硬盤上。
343
d)對於單機配置多個Redis實例的情况,可以配置不同實例分盤存儲
AOF文件,分攤硬盤寫入壓力。
運維提示
配置no-appendfsync-on-rewrite=yes時,在極端情况下可能丟失整個AOF
重寫期間的數據,需要根據數據安全性决定是否配置。
5.3.3 AOF追加阻塞
當開啟AOF持久化時,常用的同步硬盤的策略是everysec,用於平衡性
能和數據安全性。對於這種方式,Redis使用另一條線程每秒執行fsync同步
硬盤。當系統硬盤資源繁忙時,會造成Redis主線程阻塞,如圖5-5所示。
阻塞流程分析:
1)主線程負責寫入AOF緩沖區。
2)AOF線程負責每秒執行一次同步磁盤操作,並記錄最近一次同步時
間。
3)主線程負責對比上次AOF同步時間:
·如果距上次同步成功時間在2秒內,主線程直接返回。
·如果距上次同步成功時間超過2秒,主線程將會阻塞,直到同步操作完
成。
通過對AOF阻塞流程可以發現兩個問題:
1)everysec配置最多可能丟失2秒數據,不是1秒。
2)如果系統fsync緩慢,將會導致Redis主線程阻塞影響效率。
AOF阻塞問題定比特:
1)發生AOF阻塞時,Redis輸出如下日志,用於記錄AOF fsync阻塞導致
拖慢Redis服務的行為:
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
2)每當發生AOF追加阻塞事件發生時,在info Persistence統計中,
aof_delayed_fsync指標會累加,查看這個指標方便定比特AOF阻塞問題。
3)AOF同步最多允許2秒的延遲,當延遲發生時說明硬盤存在高負載問
題,可以通過監控工具如iotop,定比特消耗硬盤IO資源的進程。
優化AOF追加阻塞問題主要是優化系統硬盤負載,優化方式見上一節。
5.4 多實例部署
Redis單線程架構導致無法充分利用CPU多核特性,通常的做法是在一
臺機器上部署多個Redis實例。當多個實例開啟AOF重寫後,彼此之間會產
生對CPU和IO的競爭。本節主要介紹針對這種場景的分析和優化。
上一節介紹了持久化相關的子進程開銷。對於單機多Redis部署,如果
同一時刻運行多個子進程,對當前系統影響將非常明顯,因此需要采用一種
措施,把子進程工作進行隔離。Redis在info Persistence中為我們提供了監控
子進程運行狀况的度量指標,如錶5-2所示。
我們基於以上指標,可以通過外部程序輪詢控制AOF重寫操作的執行,
整個過程如圖5-6所示。
流程說明:
1)外部程序定時輪詢監控機器(machine)上所有Redis實例。
2)對於開啟AOF的實例,查看(aof_current_size-
aof_base_size)/aof_base_size確認增長率。
3)當增長率超過特定閾值(如100%),執行bgrewriteaof命令手動觸發
當前實例的AOF重寫。
4)運行期間循環檢查aof_rewrite_in_progress和
aof_current_rewrite_time_sec指標,直到AOF重寫結束。
5)確認實例AOF重寫完成後,再檢查其他實例並重複2)~4)步操作。
從而保證機器內每個Redis實例AOF重寫串行化執行。
边栏推荐
- 【森城市】GIS数据漫谈(二)
- C # / vb. Net supprime le filigrane d'un document word
- Use of fiddler
- Statistics of radar data in nuscenes data set
- MySQL
- 运维管理系统有哪些特色
- 差异与阵列和阵列结构和链表的区别
- 【Node学习笔记】chokidar模块实现文件监听
- How to design interface test cases? Teach you a few tips to draft easily
- The panel floating with the mouse in unity can adapt to the size of text content
猜你喜欢
S120驱动器基本调试步骤总结
Integerset of PostgreSQL
Unity custom webgl packaging template
导数、偏导数、方向导数
进程管理基础
Redis入门完整教程:复制原理
Station B's June ranking list - feigua data up main growth ranking list (BiliBili platform) is released!
Summary of basic debugging steps of S120 driver
Huitong programming introductory course - 2A breakthrough
【森城市】GIS数据漫谈(二)
随机推荐
Fundamentals of process management
unity中跟随鼠标浮动的面板,并可以自适应文字内容的大小
Wireshark installation
Overall query process of PostgreSQL
Summer Challenge database Xueba notes (Part 2)~
用全连接+softmax对图片的feature进行分类
从零安装Redis
MATLB|具有储能的经济调度及机会约束和鲁棒优化
C#/VB.NET 删除Word文档中的水印
Cloud Mail .NET Edition
Unity custom webgl packaging template
Common fitting models and application methods of PCL
【Node学习笔记】chokidar模块实现文件监听
Summary of basic debugging steps of S120 driver
记一次JAP查询导致OOM的问题分析
电气工程及其自动化
PCL 常用拟合模型及使用方法
Have fun | latest progress of "spacecraft program" activities
AWS learning notes (I)
Google Earth Engine(GEE)——Landsat 全球土地调查 1975年数据集