hhvm之轻进程

 

本文为原创,转载请注明:http://www.cnblogs.com/gistao/

 

背景

我们在aws上部署了hhvm,高峰段发现cpu idle降的比较低,只有10-20%,而使用php-fpm的另外一台机器的cpu idle在40-60%,这与hhvm的性能明显不符。

hhvm的cpu截图

分析

使用gperftools和xhprof工具分析函数的CPU耗时分布

gperf截图

xhprof截图 

分析发现_addSysInfo函数内竟然调用了一个exec函数,触发了多线程下fork的坑。不过hhvm也已经提供了相应的避免方法:轻进程

HHVM的轻进程

背景

hhvm支持exec函数对应的底层调用是popen,此函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程

由于hhvm是多线程的,为了避免fork引起的大量内存copy带来的开销,hhvm设计了轻进程模式,轻进程也就是只有一个线程的意思

设计思路

1.在hhvm启动的时候,此时只有一个线程即主线程,就fork出配置项LightProcessCount个子进程 

2.当php脚本执行exec的时候,hhvm主进程不会执行fork 

3.hhvm会根据当前worker的线程id %LightProcessCount 得到相应的”子进程标识“,“子进程标识”用于和先前fork出的子进程打交道 

4.“子进程标识”传递命令到对应的子进程,继而在子进程里完成exec相应的功能 

5.注意每个”子进程标识“有一把锁,如果锁未释放,则当前worker线程会阻塞 

6.在子进程完成exec之前,当前worker线程会阻塞

配置

Server {
    # Light process has very little forking cost, because they are pre-forked
    # Recommend to turn it on for faster shell command execution.
    #LightProcessFilePrefix = ./lightprocess
    #LightProcessCount = 0
}
LightProcessCount默认是0,hhvm根据此值建立相应数量的轻进程,如需要,建议和ThreadCount保持以致
LightProcessFilePrefix用于子进程和主进程的通信,即Unix domain socket

例子

配置如下

Server {
    #LightProcessFilePrefix = ./light_process
    #LightProcessCount = 10
}

hhvm启动后,会启动10个轻进程

gistao  10472  0.0  0.0 346980 15656 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10473  0.0  0.0 346980 15512 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10474  0.0  0.0 346980 15516 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10475  0.0  0.0 346980 15520 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10476  0.0  0.0 346980 15520 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10477  0.0  0.0 346980 15520 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10478  0.0  0.0 346980 15520 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10479  0.0  0.0 346980 15520 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10480  0.0  0.0 346980 15520 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099
gistao  10481  0.0  0.0 346980 15524 ?      Ss   17:00   0:00 hhvm-HHVM-2.2/hphp/hhvm/hhvm -vServer.LightProcessFilePrefix=./light_process -vServer.LightProcessCount=10 -m server -vEval.Jit=true -p 8099

同时,在当前运行目录下生成

srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.0
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.1
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.2
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.3
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.4
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.5
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.6
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.7
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.8
srwxr-xr-x  1 gistao hhvm        0 Jan 13 17:00 light_process.10470.9
原文地址:https://www.cnblogs.com/gistao/p/4442417.html