hhvm3.0的坑

最近新架构升级了hhvm版本,从2.2升级到了3.0,运行环境增加了一个虚拟化用的容器,结果遇到一个诡异的现象,在基本相同代码、相同压力下,cpu消耗远大于升级前。

经过仔细排查,虚拟化容器里有不少文件是软链(这是一个兄弟部门的自研容器,有大范围的实际应用),而问题就在hhvm一个叫CheckSymLink的软链配置上,该配置项说明如下:“如果php文件或其上级目录为符号链接,则__FILE__会返回实际目录地址。但开启会影响性能,所以如果目录中没有符号链接,建议关闭CheckSymLink = false” 。什么意思呢,就是说如果HHVM运行某个php文件是软连的话,会试图寻找该软连接的实际地址,但是因为目录实际是存在的,没必要非要找实际地址,所以就是浪费了性能。

加上配置项CheckSymLink = false进行测试,发现性能有大幅提升,线下对比测试cpu使用率:

hhvm_checksymlink

那为什么老架构不加上这个配置CheckSymLink = false,性能就是ok的呢,查资料后发现HHVM2.2默认CheckSymLink = false,而HHVM3.0 默认CheckSymLink = true

其它升级后的性能差异通过xhprof分析性能消耗后diff新旧代码后解决,比如iconv转码前一定要先check,必要时再转,因为这个函数太耗cpu了。(经测试,单独执行iconv函数转码在hhvm3.0下性能要比hhvm2.2性能差47%,而在输入输出编码相同的情况下性能差高达80%,此处敲黑板。hhvm2.2用的是libiconv,hhvm3.0用的是系统自带的gconv,这应该是差异的主要原因,gconv的实现相比libiconv可能存在较大的性能劣势,不排除系统自带gconv版本低的原因)

 

总结:

1)涉及到基础环境升级,必须尽可能仔细的对比新旧版本的差异部分,尤其是涉及到配置默认值发生变化的地方。

2)远低于极限性能下的压力测试可能发现不了问题,大改动下一定要做极限性能对比

3)同台机器不同cpu负荷下相同的性能测试表现不一样,建议在cpu_idle高于60%的场景下做压测

Cpu_dile的98%时候做100qps的压测,可能cpu消耗只有13%,但是在Cpu_dile为50%的情况下,同样压测,cpu消耗在30%,不是对等关系,特别是cpu_idle低于40%的时候,压测结果已不可信,这个时候机器已经不稳定,前后的cpu差值已经不是你被压测的服务的消耗了

4)不可太过相信成熟模块,在自己的应用场景下可能会出现别人出现不了的问题。

5)早点用gperftools和xhprof工具分析性能会节约不少时间

 

发表评论

电子邮件地址不会被公开。