一个上线不久,没什么访问量的网站,突然收到用户反馈说页面经常打不开,或者能打开,但是要等十几秒,卡顿非常严重,几乎无法正常使用了,自己人测试下也是相同的表现,看来问题在服务端,排除了网络影响后,就是后端有什么问题了,奇怪的是,并没有任何指标报警啊,服务器一切正常,研发表示也没有啥特别改动,程序日志也很正常。

因为卡顿情况存在,肯定有一个环节请求响应慢了,跟踪下来发现所有卡顿都是同一台云主机,检查监控指标,并不算高,但是看起来会比其他主机上的应用多吃一些CPU,重启应用无效,等手工迁移应用到其他云主机,卡顿问题立即消失,虽然不愿意承认,但是大家觉得云主机的宿主机是不是有什么问题,请厂商帮忙检查,结果是没有问题,一度陷入僵局。

经过仔细对比监控记录,发现有问题的主机上应用在凌晨闲时CPU占用率突然从2%提高到5%,而其他主机上应用一直是2%,我们把怀疑宿主机的依据给到厂商,虽然厂商觉得他们没问题,但是还是愿意帮忙做一下云主机的热迁移。好在热迁移后,问题立即消失,厂商表示不可思议,要求再迁移回来,问题马上复现,经过多次来回检验,厂商终于给出问题可能的原因:透明大页不足,导致分配到了小页,造成虚拟机性能下降。

透明大页完全依赖操作系统分配,如果内存不够富裕,碎片严重就可能无法分配到透明大页(transparent_hugepage),而被分配小页,造成虚拟机页表地址转换开销加剧,性能自然受影响,但是差到这个程度,也是出乎我的意料。难怪很多软件都要求禁用透明大页,可见确实是潜在的性能杀手。

最后解决方案,就是不要使用透明大页,直接使用大页(hugepages),qemu参数 -mem-path 指定即可。

大页是内核支持的预分配内存,一旦分配就从内存统计里消失,和透明大页是完全不同的,具体可以参考内核文档:

https://www.kernel.org/doc/Documentation/vm/transhuge.txt

https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt