PHP7.4 Preload 功能测试
PHP7.4 已经发布,发布了很多新特性,其中有一项功能比较吸引人,那就是预加载功能,可以将文件提前加载到内存当中,据说可以提升 PHP 性能,但是究竟是不是能提升,能提升多少,我们可以做一个实验来测试下。
先上github地址 https://github.com/linkkong/php7.4-preload-test
思路
预加载的原理就是将类提前加载到内存中,这种提升在 fpm 场景下最适合,所以笔者做了以下几个角度的测试。
- 速度测试:比较 php7.4 预加载、php7.4 无预加载、php7.3 三种环境下,同一份文件访问的表现
- 空间测试:也就是上面三种环境下内存使用情况
- CPU 使用的情况可以忽略,因为下面的测试使用了 docker,已经将 cpu 使用率降低到了 25%
工具
- php 项目:1) 在 www 目录下面,默认访问的是 index.php 文件,里面引用了 www/Dog 目录下的三个文件 (增加文件读取操作);
2) 为了验证预加载确实读取类到了内存中,增加了 dog 类 - 使用 docker-compose 编排了三个 php 环境分别是 php7.4 预编译、php7.4 普通、php7.3 普通
php74: image: php:7.4-fpm volumes: - ./www/:/var/www/html/:cached - ./php/preload.ini:/usr/local/etc/php/conf.d/preload.ini expose: - 9000 deploy: resources: limits: cpus: '0.25' memory: 150M php741: image: php:7.4-fpm volumes: - ./www/:/var/www/html/:cached expose: - 9000 deploy: resources: limits: cpus: '0.25' memory: 150M php73: image: php:7.3.9-fpm volumes: - ./www/:/var/www/html/:cached expose: - 9000 deploy: resources: limits: cpus: '0.25' memory: 150M
预加载比普通多了一个预加载的配置文件,把 www/Dog 里的文件进行了 opcache_compile_file
参考 php/preload.ini 和 www/preload.php - 增加 nginx 配置,参考 nginx/conf.d/default.conf
环境 Host php7.4 预加载 http://localhost:8000/ php7.4 无加载 http://localhost:8001/ php7.3 普通 http://localhost:8002/
测试
打开 2 个窗口,分别执行下面的命令,不要关闭
//监控docker容器的cpu使用和内存使用
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
//启动所有容器,必须使用--compatibility参数,否则CPU内存限制无效
docker-compose --compatibility up
运行起环境后可以看到,php74_1 是预加载环境,php741_1 是无预加载环境,php73_1 是 php7.3 环境,php7.4 预加载环境已经比无预加载环境多使用了 0.08Mib 内存,至于是不是已经预加载了类,还不能下结论
下面采用 ab 来进行简单的压测,并用每秒请求数来进行对比
ab -c 10 -n 1000 http://localhost:8000/
测试 index.php
测试 7.4 预加载、7.4 无预加载、7.3 三种环境的表现
环境和地址 | 第 1 次 | 第 2 次 | 第 3 次 | 第 4 次 | 第 5 次 |
---|---|---|---|---|---|
7.4 预加载;http://localhost:8000/ | 268 | 367 | 410 | 345 | 359 |
7.4 无预加载;http://localhost:8001/ | 153 | 180 | 160 | 137 | 190 |
7.3;http://localhost:8002/ | 154 | 110 | 126 | 134 | 131 |
测试 dog.php
dog.php 包含了 Dog 文件夹下的内容,主要测试 dog 类,是否已经在内存中。用 curl 访问即可,或者浏览器打开
环境和地址 | 运行结果 |
---|---|
7.4 预加载;http://localhost:8000/dog.php | Cannot declare interface AnimalInterface, because the name is already in use in /var/www/html/dog.php |
7.4 无预加载;http://localhost:8001/dog.php | It is runningWang! Wang! |
7.3;http://localhost:8002/dog.php | It is runningWang! Wang! |
测试 cat.php
cat.php 包含 cat 类,就是将 dog 类改了下名字全部放到了 cat.php 文件中,减少文件读写;主要测试在文件读写次数一致的情况下程序的表现
环境和地址 | 第 1 次 | 第 2 次 | 第 3 次 | 第 4 次 | 第 5 次 |
---|---|---|---|---|---|
7.4 预加载;http://localhost:8000/cat.php | 334 | 305 | 337 | 395 | 366 |
7.4 无预加载;http://localhost:8001/cat.php | 282 | 201 | 221 | 213 | 269 |
7.3;http://localhost:8002/cat.php | 219 | 247 | 216 | 295 | 254 |
总结
- php7.4 开启预加载,性能确实提升了很多,原因就是大幅度减少了文件读取的时间
- 未开启预加载的情况下,php7.3 和 php7.4 性能差距不大
- php7.4 开启了预加载后,但是并没有预加载特定文件 (Cat 类) 性能居然也有提升,原因还不得而知???
- 从第二个测试来看 php7.4 开启预加载之后,类确实加载到了内存中,这就是提升效率的关键,但是在实际项目中,这个特性可能会因为不熟悉特性重复定义类导致项目报错挂掉 (潜在的风险)
- 没有做关于 laravel 的测试,因为不想做了,原理差不多
- 在实际应用中,应该对经常使用的类进行热加载,而不要全部加载,参考下面第二个文献
最终还是做了 Laravel 的测试,见图
laravel 项目是 6.5 版本,只修改了 route/web.php,把默认返回值改成了一个 json,其他均未修改
貌似 php7.4 只要开启 preload,不需要配置 preload 文件也能加快访问速度 (原理未知,可能是自动缓存了,如果是自动缓存,那么后期更新项目就需要重启 fpm,不然会有问题),所以我在 www 目录下面放入了一个 laravel 项目,然后用 ab 进行了压测,压测结果特别低是因为对容器的 CPU 和内存做了限制。
从 2,3 图来看,没有开启 preload 的 php7.4 与 php7.3 性能相差无几,但是开启了 preload 的 php7.4,提升还是很明显的,降低了非常多的文件读取性能消耗
Laravel 第二次测试
经过韩天峰大佬指正,php7.3 和 php7.4 也应该同时开启 opcache,上面的实验提升很大其实是 opcache 的功劳。
对 laravel 的 vendor/laravel 文件进行了 preload,再次做了实验,得到如上的数据,相比较两个 php7.4 是否开启 preload 还是有差距的,但是 php7.3+opcache 的实验数据居然跟 php7.4+preload 性能接近,这个还有点想不通,需要进一步测试。也可能是 laravel 框架和 php7.4 并不适配,亦或是 opcache 开启的参数没有调优;
存在的问题
- php7.3+opcache 的实验数据居然跟 php7.4+preload 性能接近
可以改进的地方
- fpm 容器没有调优,没有设置 fpm 连接数等
- opcache 参数没有调优,只有 opcache.enable = 1;opcache.enable_cli = 1
- 没有测试数据库链接等场景,也没有评测其他框架
最后
php7.4 开启 preload 的性能依据官方评测,提升在 10% 左右,其实并不是很大了,相对开启 opcache,收益较小,而且还跟缓存的文件有关。所以这个实验也证明了,php7 以上的版本,请务必开启 opcache,因为带来的提升真的很大。
参考文献
- Composer: How it should preload in PHP 7.4
- 国外同行做的测试,可能是基于 laravel
- Preloading in PHP 7.4
- 在 Docker Compose file 3 下限制 CPU 與 Memory
原文链接:https://learnku.com/articles/37905
文章评论