1. 问题表现
分布式系统的QPS(性能)突然下降。
2. 检查了类中心节点,发现中心节点IO非常高,如下:
可以看到1. CPU的负载非常高;2. CPU项的wa非常高。
3. 检查高IO进程
如上图,使用iotop可以看到:1. io高的是我们的目标进程。2. iotop指示基本DISK READ
4. 跟正常ps对比
1. 内存:正常ps有低内存现象。 异常ps有低内存现象。
2. IO:正常ps没有高io现象。 异常ps有高io现象。
3. 负载:正常ps负载:20~30。 异常ps负载80~120。
5. 磁盘状况
iostat能监控到每块磁盘的读写。我们可以看到sdg上有大致300MB每秒的读写,跟上面IOTOP中看到的一致。
根据df拿到sdg对应的挂载点是/data7
我们使用lsof -p拿到所有该进程打开的在data7文件夹下的文件。我们发现/data7文件夹下都是.so文件。那么我们可以大致推理出程序在读取这些.so文件的是否发生了大量的IO。
我们知道so文件都是用mmap系统调用映射到内存空间的。当内存映射被换出时就会访问磁盘。怀疑内存不足导致内存映射被频繁换出。
我们通过smaps检查data7下所有的so的内存映射中对应的真实内存。发现:
正常作业 | 异常作业 | |
---|---|---|
so映射总大小 | 21856KB | 19196KB(不稳定) |
python文件总大小 | 8676KB | 5924KB(不稳定) |
TF的so大小 | 21856KB | 19140(不稳定) |
注释:
1. 稳定代表:访问.so的虚拟内存都已经映射了实际内存。(每次访问.so文件都从内存中读取数据。)
2. 不稳定代表:访问.so的虚拟内存时,需要从磁盘中将对应数据读入cache后,才能访问.so。(每次函数调用都从磁盘中先加载.so才能调用)
根据上述观点,应该会有大量的页错误发生。
6. 页错误情况
6.1 异常情况
6.2 正常情况
对比可以看到确实有大量的缺页错误。
7. 内存隔离引入额外水线
因为内存是隔离的。cgroup有自己的一套逻辑。虽然看着系统内存还有,但进程内存不够了。其实进程是看不到系统内存的,他只能看到cgroup的内存。
所以就出现了,系统还有内存但进程内存不足的情况。
8. 总结
1. 高IO是由于.so/python等磁盘文件的内存映射抖动引起的。
2. 磁盘文件的内存映射抖动是因为ps内存达到低水线而又不满足OOM kill导致的。
9. 改正
启动线程,监控smaps。如果内存抖动则报警。
10. 反思
没有考虑到cgroup隔离内存情况。才会出现机器内存多余而进程内存不足的问题。