PHP7.4 Preload 效能測試

Lingkong發表於2019-12-11

PHP7.4已經發布,釋出了很多新特性,其中有一項功能比較吸引人,那就是預載入功能,可以將檔案提前載入到記憶體當中,據說可以提升PHP效能,但是究竟是不是能提升,能提升多少,我們可以做一個實驗來測試下。

 先上github地址     https://github.com/linkkong/php7.4-preload-test

思路

預載入的原理就是將類提前載入到記憶體中,這種提升在fpm場景下最適合,所以筆者做了以下幾個角度的測試。

  1. 速度測試:比較php7.4預載入、php7.4無預載入、php7.3三種環境下,同一份檔案訪問的表現
  2. 空間測試:也就是上面三種環境下記憶體使用情況
  3. CPU使用的情況可以忽略,因為下面的測試使用了docker,已經將cpu使用率降低到了25%

工具

  1. php專案:

    1) 在www目錄下面,預設訪問的是index.php檔案,裡面引用了www/Dog目錄下的三個檔案(增加檔案讀取操作);
    2) 為了驗證預載入確實讀取類到了記憶體中,增加了dog類

  2. 使用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

  3. 增加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記憶體,至於是不是已經預載入了類,還不能下結論
PHP7.4 Preload 效能測試
下面採用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

總結

  1. php7.4開啟預載入,效能確實提升了很多,原因就是大幅度減少了檔案讀取的時間
  2. 未開啟預載入的情況下,php7.3和php7.4效能差距不大
  3. php7.4開啟了預載入後,但是並沒有預載入特定檔案(Cat類)效能居然也有提升,原因還不得而知???
  4. 從第二個測試來看php7.4開啟預載入之後,類確實載入到了記憶體中,這就是提升效率的關鍵,但是在實際專案中,這個特性可能會因為不熟悉特性重複定義類導致專案報錯掛掉(潛在的風險)
  5. 沒有做關於laravel的測試,因為不想做了,原理差不多
  6. 在實際應用中,應該對經常使用的類進行熱載入,而不要全部載入,參考下面第二個文獻

最終還是做了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,提升還是很明顯的,降低了非常多的檔案讀取效能消耗

PHP7.4 Preload 效能測試


Laravel第二次測試

經過韓天峰大佬指正,php7.3和php7.4也應該同時開啟opcache,上面的實驗提升很大其實是opcache的功勞。

PHP7.4 Preload 效能測試

對laravel的vendor/laravel檔案進行了preload,再次做了實驗,得到如上的資料,相比較兩個php7.4是否開啟preload還是有差距的,但是php7.3+opcache的實驗資料居然跟php7.4+preload效能接近,這個還有點想不通,需要進一步測試。也可能是laravel框架和php7.4並不適配,亦或是opcache開啟的引數沒有調優;

存在的問題

  1. php7.3+opcache的實驗資料居然跟php7.4+preload效能接近

可以改進的地方

  1. fpm容器沒有調優,沒有設定fpm連線數等
  2. opcache引數沒有調優,只有 opcache.enable = 1;opcache.enable_cli = 1
  3. 沒有測試資料庫連結等場景,也沒有評測其他框架

最後

php7.4開啟preload的效能依據官方評測,提升在10%左右,其實並不是很大了,相對開啟opcache,收益較小,而且還跟快取的檔案有關。所以這個實驗也證明了,php7以上的版本,請務必開啟opcache,因為帶來的提升真的很大。

參考文獻

  1. Composer: How it should preload in PHP 7.4
  2. 國外同行做的測試,可能是基於laravel
  3. Preloading in PHP 7.4
  4. 在 Docker Compose file 3 下限制 CPU 與 Memory
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章