PS:由于上传图片太麻烦了,就传了个附件,在文章最后结尾处

关于HHVM多线程介绍

PHP-FPM 服务启动时有多个进程。并且随着请求压力增大,还会增加进程。HHVM 只有一个进程服务。因为 HHVM 是多线程的设计。这里简略介绍下 HHVM 的架构设计。

HHVM 架构设计

HHVM 中所有 I/O 都是非阻塞的。在 HHVM 中有两种线程:I/O 线程 和 HHVM 线程。分为以下三种功能:

一个I/O线程负责接受连接。
由一组I/O线程负责处理已打开的连接。在高负载情况下,每个CPU一个线程。这也是最优配置。对新连接,使用Round-Robin负载均衡算法进行分配。I/O线程不会因等待单个连接而阻塞。只有在I/O线程处理的所有连接都不活跃时,I/O线程才会进入阻塞状态。当在阻塞的线程被选中调度或者类似的系统事务时,才会结束阻塞状态。
HHVM 线程负责执行 PHP。它们可能会在等待消息主体时发生阻塞(通常会在表单提交大量数据发生)。翻译缓存(opcache?)共享给所有 HHVM 线程。即使请求处理完毕后也会继续保持在缓存中。这个特性和JIT搭配使用非常棒。当多次执行相同文件时,可以看到显著的性能提升。

查看hhvm进程中的多线程

# ps -eLf |grep hhvm# pstree |grep hhvm     |-hhvm---17*[{hhvm}]
HHVM 轻进程 http://reeze.cn/2014/08/23/multi-thread-service-and-fork/

性能测试——HHVM 高性能PHP虚拟机

集成的扩展:https://github.com/facebook/hhvm/wiki/Extensions
性能提升多少?看测试脚本:https://github.com/ckwalsh/php_hhvm_bench
百度使用hhvm:http://lamp.baidu.com/2014/11/04/hhvm-in-baidu/
百度出版《HHVM应用实践 》:http://lamp.baidu.com/hhvm/hhvm-in-action/

一、安装HHVM

参考:
https://blog.linuxeye.com/396.html
https://github.com/facebook/hhvm/wiki/Building-and-installing-HHVM-on-CentOS-6.3
https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Centos-6.x

官方建议使用yum方式进行安装,所以这里使用yum进行了安装
目前,HHVM只能在centos6.2以上的系统中使用

1、配置epel、gleez、remi yum源
# rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
2、安装HHVM依赖包
#yum -y install libmcrypt-devel glog-devel jemalloc-devel tbb-devel libdwarf-devel mysql-devel \libxml2-devel libicu-devel pcre-devel gd-devel boost-devel sqlite-devel pam-devel \bzip2-devel oniguruma-devel openldap-devel readline-devel libc-client-devel libcap-devel \libevent-devel libcurl-devel libmemcached-devel  --nogpgcheck

提示有很多包需要升级,这时需要看情况决定,因为升级时需要使用参数“--skip-broken”比较暴力

3、从remi源中
# rpm -Uvh 
 # rpm -Uvh 
  # yum -y --enablerepo=remi install libwebp mysql mysql-devel mysql-lib  --nogpgcheck

问题:

ERROR with rpm_check_debug vs depsolve:
libmysqlclient.so.16()(64bit) is needed by postfix-2:2.6.6-6.el6_5.x86_64
libmysqlclient.so.16(libmysqlclient_16)(64bit) is needed by postfix-2:2.6.6-6.el6_5.x86_64 
You could try running: rpm -Va --nofiles --nodigest
Your transaction was saved, rerun it with: yum load-transaction /tmp/yum_save_tx-2015-01-28-16-56H0a1Qj.yumtx

google搜索关键字”libmysqlclient.so.16()(64bit) “ ,下载相应的rpm包,并进行安装:

# wget  
 # rpm -ivh mysqlclient16-5.1.61-1.ius.centos6.x86_64.rpm

再进行安装

4、安装HHVM
#yum -y --nogpgcheck install hhvm

可能会出现问题:

error: Failed dependencies:        
libboost_regex.so.1.54.0()(64bit) is needed by hhvm-3.5.0-4.el6.x86_64        
libicudata.so.42()(64bit) is needed by hhvm-3.5.0-4.el6.x86_64        
libicui18n.so.42()(64bit) is needed by hhvm-3.5.0-4.el6.x86_64        
libicuuc.so.42()(64bit) is needed by hhvm-3.5.0-4.el6.x86_64

依赖之间还存在着依赖关系,需要先解决” libicuuc“,再行解决”libboost_regex“:

#  wget 
 #  rpm -ivh libicu-4.2.1-8.1.x86_64.rpm 
 # wget http://yum.gleez.com/6/x86_64/boost-regex-1.54.0-9.el6.x86_64.rpm# rpm -ivh boost-regex-1.54.0-9.el6.x86_64.rpm

问题2:

** Found 2 pre-existing rpmdb problem(s), 'yum check' output follows:
boost-regex-1.54.0-9.el6.x86_64 is a duplicate with boost-regex-1.41.0-11.el6_1.2.x86_64
libicu-4.2.1-9.1.el6_2.x86_64 is a duplicate with libicu-4.2.1-8.1.x86_64 
# yum erase libicu-4.2.1-8.1.x86_64
# yum erase boost-regex-1.41.0-11.el6_1.2.x86_64

出现这个问题的原因是由于装了更新的版本,所以卸载了旧版本之后就可以了

查看版本号:

# hhvm --versionHipHop VM 3.5.0-dev+2014.12.11 (rel)Compiler: 
heads/master-0-g546087bf1b0560c4a9e254fcad46a9212e42ccc2Repo schema: 
cf1780b3cc3857e091e924935ae6267e9794de9cExtension API: 20140829
5、配置HHVM

安装HHVM时,会默认创建一个nginx用户,并以nginx启动服务,可以进行修改:
删除nginx用户

#userdel -r nginx

修改HHVM目录权限

#chown -R www.www /var/run/hhvm#chown -R www.www /var/log/hhvm

默认的HHVM配置是没有设置socket的,所以我们需要修改HHVM配置

vim /etc/hhvm/server.ini
; php options
pid = /var/run/hhvm/pid
; hhvm specific
hhvm.server.port = 9001
hhvm.server.type = fastcgi
hhvm.server.default_document = index.php
hhvm.log.use_log_file = true
hhvm.log.file = /var/log/hhvm/error.log
hhvm.repo.central.path = /var/run/hhvm/hhvm.hhbc
;以下是修改信息
hhvm.server.file_socket = /var/run/hhvm/sock 

vim /etc/hhvm/php.ini
session.save_handler = files
session.save_path = /var/lib/php5
session.gc_maxlifetime = 1440
; hhvm specific
hhvm.log.level = Warning
hhvm.log.always_log_unhandled_exceptions = true
hhvm.log.runtime_error_reporting_level = 8191
hhvm.mysql.typed_results = false
;以下是修改信息hhvm.mysql.socket = /tmp/mysql.sock    
;指定mysql.sock路径(HHVM默认路径sock路径是/var/lib/mysql/mysql.sock) 

# service hhvm restart

需要注意的是:session.save_handler、session.save_path,这两个参数需要根据实际情况进行修改。例如:使用了memcache,那么就需要根据/etc/php.ini 上的配置就行修正/etc/hhvm/php.ini
如:
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11210?persistent=1"

修改 nginx.conf/vhost.conf 配置,使其使用HHVM

#添加/修改 fastcgi_passfastcgi_pass  unix:/var/run/hhvm/sock;

修改HHVM以www运行

# vim /etc/init.d/hhvmUSER=www

启动HHVM

# /etc/init.d/hhvm startStarting Hhvm:                                             [  OK  ]#./nginx_reload

二、性能测试:

参考:
http://blog.csdn.net/lxlmj/article/details/23268605

1、单次测试:

主要测试CPU、IO、内存方面的性能

time php testcpu.php                                 #使用php方式运行
time hhvm testcpu.php                              #使用hhvm方式运行(未开启Jit)
time hhvm -v"Eval.Jit=true" testcpu.php  #使用hhvm的Jit方式运行

分别创建了三个php脚本来测试CPU、IO、内存(cpu操作密集型代码、IO操作密集型代码、MEM操作密集型代码)

CPU:

使用cpu操作密集型代码进行测试,并获取其执行所有时间进行对比
使用hhvm运行所耗时间明显比使用php运行少,说明cpu执行效率得到很大的提高

spacer.gif

IO:

使用IO操作密集型代码进行测试,并获取其执行所有时间进行对比
使用hhvm运行所耗时间与使用php运行所耗时间相差无几,说明hhvm对IO性能没有多大的优化或者提高

spacer.gif

MEM:

使用MEM操作密集型代码进行测试,并获取其执行所有时间进行对比
使用hhvm运行所耗时间明显比使用php运行少,执行效率大概提高了一倍左右

spacer.gif

在单次测试中:
1、HHVM对CPU性能优化提升不少,执行效率有很大的提高
2、HHVM对IO读写性能方面没有提升
3、HHVM对内存性能优化上大概提升了一倍左右

2、并发测试

并发测试,是通过修改环境配置,对opcache、HHVM 分别进行了测试,使用的仍是上面所使用的php脚本

并发测试都是模拟并发10个用户,运行20秒进行测试;通过比较Speed进行比较

IO测试

进行IO测试时有问题,没法正常执行php(不懂php。。)

CPU测试

分析以下测试数据,HHVM cpu执行效率提升50倍左右

不使用HHVM or opcache

Speed=30

spacer.gif

opcache

Speed=30

spacer.gif

HHVM

Speed=1542

spacer.gif

MEM测试

分析以下测试数据,HHVM内存的执行效率大概提升了200%

不使用HHVM or opcache

Speed=87

spacer.gif

opcache

Speed=111

spacer.gif

HHVM

Speed=351

spacer.gif

本次测试中:
1、可以看出HHVM 对CPU性能有很高的提升(竟然可以达到50倍,参考的文章是30倍)
2、HHVM对内存的性能也有提高,大概300%左右
3、对于IO的测试,并没有正常地创建1000个文件在指定路径,判断为该php没有执行成功

3、使用ab压测wordpress首页:

利用ab进行压测,通过比较Time taken (花费的时间)、Requests per second(每秒钟处理的请求数)

对以下数据进行比较:

spacer.gif

1、使用opcache相对于不使用opcache来说,速度大概增加了 一倍;CPU、内存消耗情况接近。
2、使用HHVM后,就以上测试数据来看,效率提高相当明显(7倍左右);相应的,CPU、内存消耗则也增加了不少。

3.1、不使用HHVM or opcache

spacer.gif

此时:cpu使用为60%,内存使用为1440M

spacer.gif

3.2、使用opcache

spacer.gif

此时:cpu使用为60%,内存使用为1403M

spacer.gif

3.3、使用HHVM

spacer.gif

此时cpu使用为88%,内存使用为1624M

spacer.gif

三、小结

就上述测试:

1、使用opcache相对于不使用opcache来说,速度大概增加了 一倍;CPU、内存消耗情况接近。
2、使用HHVM后,就以上测试数据来看,效率提高相当明显(7倍左右);相应的,CPU、内存消耗则也增加了不少。
3、对IO、CPU、MEM进行测试时,是使用网上的代码
4、CPU、内存 执行效率提高

四、压测router机

1、不使用HHVM or opcache
# time python tgzt_web.py
#time 1real    2m44.081suser    0m1.578ssys     0m0.242s
#time 2real    2m43.036suser    0m1.502ssys     0m0.252s

spacer.gif

2、opcache
# time python tgzt_web.py
#time 1real    2m40.062suser    0m1.504ssys     0m0.279s
#time 2real    2m39.941suser    0m1.553ssys     0m0.255s

spacer.gif

缓存命中情况

spacer.gif

3、hhvm
# time python tgzt_web.py
#time 1real    1m27.994suser    0m1.258ssys     0m0.214s
#time 2real    1m26.464suser    0m1.245ssys     0m0.197s

spacer.gif

4、hhvm+opcache
# time python tgzt_web.py
#time 1real    1m25.310suser    0m1.355ssys     0m0.211s

没有利用到opcache

spacer.gif

spacer.gif

五、小结

1、对于该脚本来说,使不使用opcache效果没有多大区别,但是就缓存命中情况来说,命中率还是很高的,达99%
2、使用HHVM后,运行时间明显减少,大概一倍;相应的,cpu、内存消耗也是有些增加,估计说明了HHVM对cpu、内存的执行效率是提高了