SHM共享内存问题解决
1. 问题描述
目前,现网HP刀片业务主机(部署Solaris10操作系统)经常出现内存利用率99.8%以上的情况。top命令显示如下,其中free man值为200M左右,最低时达到192M。
load averages: 0.19, 0.18, 0.18; up 293+14:44:54 17:13:27
261 processes: 254 sleeping, 6 zombie, 1 on cpu
CPU states: 98.8% idle, 0.4% user, 0.7% kernel, 0.0% iowait, 0.0% swap
Memory: 12G phys mem, 224M free mem, 20G total swap, 19G free swap
问题:由于第三方网管系统也采用类似的采集内存利用率方式,导致现网业务主机频繁告警,影响客户满意度,急需解决。
2. 原因分析
通过对现网的x86&Solaris业务主机分析,采用SHM方式申请共享内存的主机具有以下特点:
1. free内存呈周期振动波形;
波峰最大值为剩余内存总量(去掉业务和操作系统占用值);
波谷最小值为物理内存的1/64;
振幅为500M左右(根据测试主机获取),即振动直径1G左右;
周期与网关接收消息速度有关,速度越快,周期越短,速度接近0时,波形无变化。
波形图如下:
2. Kernel占用内存较高;
YNKM-PS-ISMG3-SV3-MCPP#echo ::memstat|mdb -k
Page Summary Pages MB %Tot
------------ ---------------- ---------------- ----
Kernel 707050 2761 23%
Anon 1943734 7592 62%
Exec and libs 5672 22 0%
Page cache 168250 657 5%
Free (cachelist) 2764 10 0%
Free (freelist) 313599 1224 10%
Total 3141069 12269
Physical 3081472 12037
SXTY-PS-ISMG-SV-APP10# echo ::memstat|mdb -k
Page Summary Pages MB %Tot
------------ ---------------- ---------------- ----
Kernel 894380 3493 21%
Anon 2777736 10850 66%
Exec and libs 11594 45 0%
Page cache 57855 225 1%
Free (cachelist) 156225 610 4%
Free (freelist) 293646 1147 7%
Total 4191436 16372
Physical 4101942 16023
SXTY-PS-EISMG-SV-APP13# echo ::memstat|mdb -k
Page Summary Pages MB %Tot
------------ ---------------- ---------------- ----
Kernel 901691 3522 29%
Anon 1060669 4143 34%
Exec and libs 9600 37 0%
Page cache 104997 410 3%
Free (cachelist) 516230 2016 16%
Free (freelist) 547882 2140 17%
Total 3141069 12269
Physical 3081472 12037
具体信息请参考分析文档:
3. Solaris技术支持
针对这个问题与Solaris工程师做了沟通,并且将该测试代码发给了Solaris工程师,他们做了测试,当时反馈,Solaris确实存在该问题,但只是显示上的问题,系统真实的内存还是剩余4G。我们进行了申请内存并使用的测试,发现确实如Solaris工程师所说。他们当时的解释是:对于SHM池,Solaris为了提升效率,系统会不断使用新的页,当内存不满时,使用过的内存页不释放,但是如果新申请内存,会释放内存页以满足系统需求。
4. 解决方案
1) 增加内存或较少消息池大小
测试主机中,有2台主机消息池较小,相应的free内存值也较大。以其中一台为例,
YNKM-SN5F-E08-GWMCPP-HP460C-1#echo ::memstat|mdb -k
Page Summary Pages MB %Tot
------------ ---------------- ---------------- ----
Kernel 457902 1788 15%
Anon 1335346 5216 43%
Exec and libs 10156 39 0%
Page cache 83726 327 3%
Free (cachelist) 399980 1562 13%
Free (freelist) 853959 3335 27%
Total 3141069 12269
Physical 3081472 12037
其中,普通用户账户占用内存43%,Kernel占用内存15%,free内存40%。
注:计算普通用户占用内存量可用pmap命令获得,如:
YNKM-SN5F-E08-GWMCPP-HP460C-1:pmap -x 3475
3475: mcpp-patch-2.1.3
Address Kbytes RSS Anon Locked Mode Mapped File
0000000000400000 1348 996 - - r-x-- mcpp-patch-2.1.3
0000000000560000 128 48 4 - rw--- mcpp-patch-2.1.3
0000000000580000 60 32 - - rw--- mcpp-patch-2.1.3
000000000058F000 2888 2876 8 - rw--- [ heap ]
FFFFFD7FFFDF0000 64 64 8 - rw--- [ stack ]
---------------- ---------- ---------- ---------- ----------
total Kb 2057580 1707748 64 -
优点:
1. 短时间内可用临时解决内存不够问题,测试用例中,4天均未出现内存不足问题。
缺点:
1. 浪费部分内存空间;
以消息量计算,正常情况下12G内存可用部署(MC350万消息,SR消息池350万,文件池200万),而现在只能部署(MC200万消息,SR消息池200万,文件池100万)。
2. 长时间无法保证free内存足够;
以网关为例,12G物理内存,Kernel占用29%,free内存最低1500M左右。
SXTY-PS-EISMG-SV-APP13# echo ::memstat|mdb -k
Page Summary Pages MB %Tot
------------ ---------------- ---------------- ----
Kernel 901691 3522 29%
Anon 1060669 4143 34%
Exec and libs 9600 37 0%
Page cache 104997 410 3%
Free (cachelist) 516230 2016 16%
Free (freelist) 547882 2140 17%
Total 3141069 12269
Physical 3081472 12037
2) 修改操作系统参数
鉴于Kernel占用了不少内存,咨询Solaris技术支持无果后,决定修改操作系统参数解决。
查阅《Oracle Solaris 可调参数参考手册》后发现,lotsfree参数可以满足需求,具体说明请参考文献。
修改系统参数,设置内存pageout阀值为1G(等于262144*pagesize)
# vi /etc/system
添加
set lotsfree=262144
#reboot
测试结果:
采用top命令查看free内存值,符合预期,系统free内存最低为1G
测试影响:
采用vmstat命令查看系统page信息,其中,pi,po,sr三项值未见明显异常。
优点:
1. 满足free内存最低要求;
缺点:
1. 需要修改系统参数,增加意外风险;
2. 降低了系统处理能力,不能最大限度发挥系统缓存特点。
5. 参考文献
1.《Oracle Solaris 可调参数参考手册》
2.《网贴:Solaris内存管理以及判定内存是否够用的方法》