1. 服务器环境以及配置
【机型】
处理器: | Hygon C86 7285 |
内存: | 16G |
【内核版本】
【 OS 镜像版本】
0518-server
【 nkvers 命令输出】
2. 问题现象描述
客户现场红帽系统所在平台为 intel:
版本如下:
银河麒麟操作系统所在平台为海光:
版本如下:
将程序从红帽迁移至麒麟后, 在同样的压测下, 银河麒麟操作系统上该进程 cpu 占用明显升高。
红帽上面的 top 看到 hostl 进程占用 cpu 约为 151%
而银河麒麟操作系统上 top 看到的 hostl 进程占用 cpu 约为 380%
3. 问题分析
在银河麒麟操作系统上, 通过 top -Hp 查看该进程的线程占用情况如下:
然后 strace -p 跟踪每个线程的 pid, 发现所有线程都在不停的进行 nanosleep,可以知道应用在不停的调用系统的 nanosleep 函数:
通过 perf -p 采样信息来看, 消耗主要是在__pv_queued_spin_locak_slowpath函数:
继续perf -g采样,可以看到__nanosleep最终会调用__pv_queued_spin_lock_slowpath。 结合 strace 跟踪到的系统调用来看, 也可以看出应用在不停的调用 nanosleep, 从而导致 cpu 使用率的上升。
那么为什么同样的代码, 麒麟和海光的组合, cpu 使用率会高很多, 这个怀疑和海光平台有关, 怀疑在压测环境下, 程序不停调用 nanosleep, 海光平台比 intel 平台开销增大, 和系统无关。
为了验证上述结论, 我们编写了如下测试代码进行测试, 循环执行 1 万次nanosleep 1ms。 分别在红帽-inetl, 麒麟-海光, 麒麟-intel 上分别做测试。
测试结果如下:
红帽-intel 耗时约 11s:
麒麟-海光耗时约为 13s:
麒麟-intel 耗时约为 11s,基本和红帽-intel 持平, 而且 cpu 使用率也和红帽-intel 持平。
4. 问题分析结果
从 strace 以及 perf 的分析, 程序不停的调用系统 nanosleep 增加了系统的开销。 而海光平台相较于 intel 平台, 在现场压测环境中, 海光平台的开销较大。
5. 解决方案
在海光平台上面, 应用厂家尽量不要频繁调用系统 nanosleep 函数, 可以考虑变更一下代码, 走其他的系统调用方式。