业务反馈glog组件在Docker容器内运行延时比虚拟化机要高出不少,并提供了复现的程序,复现测试程序关键代码如下:
问题有复现方法就比较好办了,运行测试程序然后采用性能调试工具perf抓取进程热点如下:
从perf信息可以看到测试程序时间主要是消耗在内核函数lru_add_drain_all上,查看内核这个函数的实现我们可以看到
这个函数的运行效率是跟cpu核心数强相关的:
在普通虚拟机上测试性能较好是因为普通虚拟机用的是8核的机器,而Pod所在的node(虚拟机)是64核的,虽然Pod通过cpu limit限制了cpu 资源上限,但是在内核里实际上还是读取的整个node的cpu核心数量。为了验证排查结论,通过将node的kernel启动参数nr_cpus修改为8后重启机器验证性能确实得到提升:
对比同一个node限制nr_cpus数量后的测试数据可以看到限制为8核后延时得到了很大改善:
既然已经确认了问题,那么怎么解决呢?
前面perf的信息已经显示了内核调用链是通过sys_fadvise64触发的,那么对应到用户态接口就是posix_fadvise函数,查看glog源码
也就是由下面的代码触发的问题,那么只要通过设置--drop_log_memory = false标志禁用glog的fadvise就能规避整个问题了:
if (FLAGS_drop_log_memory) {
if (file_length_ >= logging::kPageSize) {
// don't evict the most recent page
uint32 len = file_length_ & ~(logging::kPageSize - 1);
posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED);
}
}
增加--drop_log_memory = false后延时基本控制在3ms内:
git上也已经相关的修复补丁:
https://github.com/google/glog/pull/145
https://github.com/durswd/glog/commit/584efaa474e72b6c107358b32b2b57d84821802a
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。