PHP5加载文件耗费CPU和内存过高的问题
问题描述
200.185服务器晚上很卡,一直以为是最优参数的问题,但是通过记录晚上的CPU、MEM、PHP进程信息,发现指标评测的进程占用CPU和内存很厉害。
以3.24日的数据为例,zbpc的process_data进程,占用CPU约60%,内存约20%
且该进程经常一起来就不中断了。
排查过程
猜测有如下几个可能:
1.数据库操作过多,且没有批量进行
2.加载的文件太大,类似主力选股平的问题
3.表太大
4.程序本身存在问题
经过检查,排除了1和3,最终发现有两个问题:
1.指标评测会将请求结果先写入本地文件,然后再读取本地文件解析入库,这些本地文件最大的达到了37M
2.程序存在BUG,当计算没有完成时,会不停的重复解析本地文件,执行数据库读写操作
解决方案
死循环问题好解决,修复程序就可以了
本地文件的解析,不好处理,文件格式不利于逐行解析。
之前有测试过PHP7做文件操作效率很高,因此用PHP7在205.235上测试了下(后端脚本解析文件,然后入库,不涉及其他PHP扩展,正好适用):
1 | |
因此最终在200.186上安装了PHP7,专门用于一些后端脚本的执行。
修改效果
去掉了程序BUG,process_data进程平时耗费的CPU为0,内存从20%降低到13%左右。
解析数据时的状态待收集。
待优化项
3.25晚上20点30分查看了下,内存占用接近75%。
查看了指标评测的进程,发现process_data一直占据着13%的内存,到/proc/pid/status中看了下:
1 | |
这个不正常,太大了,需要后续改进。主要方案为:
1.该进程不需要常驻,考虑将请求数据的进程号写入本地文件,然后每隔几分钟读取文件来启动这个process_data的解析进程
(考虑到请求脚本可能需要多次执行,这里不能用进程号来作为唯一标识,应该改为日期来标记;如果超过一天没算完,产品就出问题了,属于异常现象)
2.查看下是哪个环节导致了内存这么大,修正掉
2016.03.28
将请求和解析的定时任务拆分为2个脚本,其中解析数据的脚本不再一直执行,而是每隔30分钟执行一次,降低内存消耗。
同时增加了请求状态表,便于观察当前数据更新的进度。
下午发布后,对比25日数据,发现内存消耗有明显的降低,相同时段降低了大约15%。