remiレポジトリで導入したPHP7でも十分な高速化を実現できましたが、環境に合わせた最適化コンパイルを行えばさらに速くなるらしいので試してみました。
1.目的と前提条件
CentOS6で稼働しているWordPressをさらに高速化するためにPHP7をコンパイルします。
Apacheは2.2でMPMはPreforkを利用し、OpcacheとAPCu/APC互換モジュールを利用できるようにします。これはWordPressの001 Prime Strategy Translate AcceleratorプラグインをAPCuでで利用するためにはAPC互換モジュールも導入するがあるのですが、PHP7からAPCuと分離されたとのことなので別途導入する必要があるためです。
作業はすべてrootユーザで実施。事前に「yum remove php」でPHPを削除しておきます。
また色々と厄介なSELiinuxは無効化(厳密にはPermissiveモードに)しています。
2.コンパイルに必要なパッケージをインストールする
PHPコンパイルによる高性能のFastCGIウェブサーバー構築とチューニングに関するお話し(2)の「ビルド環境構築」を参考にパッケージを導入しました。
3.PHP7の最新版安定版をダウンロードする
Current Stable PHP 7.X.Xで最新のPHP7の最新版を探しダウンロードします。
# cd /root # wget -q http://jp2.php.net/get/php-7.0.5.tar.gz/from/this/mirror -o php-7.0.5.tar.gz # tar zxvf php-7.0.5.tar.gz # cd php-7.0.5
4.APCu/APCu_bcをダウンロードする
OPcacheは標準で組み込まれていますが、APCuとAPCu_BCはPHP7対応バージョンをサイトからダウンロードする必要があります。またapcu_bcをビルドする際に、親モジュールとなるapcuの参照パスが「apcu」以外だとエラーになってしまうため、ディレクトリ名を変更します。apcu_bcのディレクトリ名もも念のため変更しておきます。
## モジュールのソースを設置するディレクトリextに移動 # cd ext/ ## APCuをダウンロードし解凍する # wget -q https://pecl.php.net/get/apcu-5.1.3.tgz # tar zxvf apcu-5.1.3.tgz # # # APCu_bcをダウンロードし解凍する # wget -q https://pecl.php.net/get/apcu_bc-1.0.3.tgz # tar zxvf apcu_bc-1.0.3.tgz ## apcu_bcのビルド時エラー対策 # mv apcu-5.1.3 apcu # mv apcu_bc-1.0.3 apcu_bc
5.ビルドの準備を行う
APCu/APCu_bv拡張モジュールをPHP7のビルドに組み込み、結果を確認します。
# cd .. # rm -rf configure # ./buildconf --force Forcing buildconf Removing configure caches rebuilding aclocal.m4 rebuilding configure rebuilding main/php_config.h.in ## configureヘルプにapcの項目が増えていればモジュールの組み込みが完了 # ./configure --help| grep apc --enable-apcu Enable APCu support --disable-apcu-rwlocks Disable rwlocks in APCu --enable-apcu-debug Enable APCu debugging --enable-apcu-clear-signal Enable SIGUSR1 clearing handler --disable-apcu-mmap Disable mmap, falls back on shm --enable-apcu-spinlocks Use spinlocks before flocks --enable-apc Enable APCu BC support
6.最適化オプションを追加しconfigureを実施
configureに最適化オプションを環境変数で渡して実行します。「-O2」は最適化レベル、「-march=native」は現在のCPUに特化したコードを生成するオプションです。
そして今回はconfigureにWordPressの動作に必要なモジュール設定と、APCu/APCu_bcを有効化させる「–enable-apcu」「–enable-apc」を加えて実行します。
を追加
export CFLAGS="-O2 -march=native -pipe" export CXXFLAGS="${CFLAGS}" ./configure \ --prefix=/usr/bin/php7 \ #PHP7のインストール先 --with-config-file-path=/etc/php7 \ #PHP7の設定ファイル保存先 --enable-apcu \ --enable-apc \ --enable-mbstring \ --enable-zip \ --enable-bcmath \ --enable-pcntl \ --enable-ftp \ --enable-exif \ --enable-calendar \ --enable-sysvmsg \ --enable-sysvsem \ --enable-sysvshm \ --enable-wddx \ --with-curl \ --with-mcrypt \ --with-iconv \ --with-gmp \ --with-pspell \ --with-gd \ --with-jpeg-dir=/usr \ --with-png-dir=/usr \ --with-zlib-dir=/usr \ --with-xpm-dir=/usr \ --with-freetype-dir=/usr \ --enable-gd-native-ttf \ --enable-gd-jis-conv \ --with-openssl \ --with-pdo-mysql=/usr \ --with-gettext=/usr \ --with-zlib=/usr \ --with-bz2=/usr \ --with-recode=/usr \ --with-mysqli=/usr/bin/mysql_config \ --with-apxs2=/usr/sbin/apxs
※参考1 検証用CentOSのCPU情報
# cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 18 model : 1 model name : AMD A8-3820 APU with Radeon(tm) HD Graphics stepping : 0 cpu MHz : 2495.462 cache size : 1024 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 6 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow constant_tsc tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni cx16 popcnt hypervisor lahf_lm extapic abm sse4a misalignsse 3dnowprefetch osvw bogomips : 4990.92 clflush size : 64 cache_alignment : 64 address sizes : 40 bits physical, 48 bits virtual power management:
※参考2 お名前.comVPSサーバのCPU情報
# cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 15 model name : Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz stepping : 11 microcode : 1 cpu MHz : 2593.746 cache size : 4096 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx lm constant_tsc arch_perfmon rep_good unfair_spinlock pni ssse3 cx16 hypervisor lahf_lm bogomips : 5187.49 clflush size : 64 cache_alignment : 64 address sizes : 40 bits physical, 48 bits virtual power management:
7.PHP7のコンパイルとインストール
configureが完了したらいよいよコンパイルです。「-j10」で並列化したコンパイルを行い、make testでコンパイルされたPHP7の動作検証を行います。この中でmake testが一番時間が掛かった処理でした。確か20分以上は掛かったはずです。
最後に一度httpdを停止してから「make install」でPHP7をサーバにインストールします。
# make -j10 # make test # service httpd stop # make install
8.PHP7/Opcache/APCuの初期設定を行とApcheを起動
インストール完了後、PHP/Opcache/APCu/mbstringの初期設定を/etc/php7/php.iniに書き込みます。設定内容はremiレポジトリでインストールしたPHP7のものを参考にしています。
# /etc/php7/php.ini max_execution_time=600 memory_limit=128M error_reporting=0 display_errors=0 log_errors=0 user_ini.filename= realpath_cache_size=2M cgi.check_shebang_line=0 date.timezone = "Asia/Tokyo" zend_extension=opcache.so [opcache] opcache.enable=1 ;opcache.enable_cli=0 opcache.memory_consumption=64 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 ;opcache.max_wasted_percentage=5 ;opcache.use_cwd=1 ;opcache.validate_timestamps=1 opcache.revalidate_freq=2 opcache.revalidate_path=0 ;opcache.save_comments=1 opcache.fast_shutdown=1 ;opcache.enable_file_override=0 opcache.optimization_level=0xffffffff ;opcache.inherited_hack=1 ;opcache.dups_fix=0 ;opcache.blacklist_filename=/etc/php.d/opcache*.blacklist ;opcache.max_file_size=0 ;opcache.consistency_checks=0 ;opcache.force_restart_timeout=180 ;opcache.error_log= ;opcache.log_verbosity_level=1 ;opcache.preferred_memory_model= ;opcache.protect_memory=0 ;opcache.restrict_api= ;opcache.file_cache= ;opcache.file_cache_only=0 apc.enabled = 1 apc.enable_cli=1 apc.shm_size=40M apc.ttl=3600 apc.gc_ttl=3600 apc.mmap_file_mask=/tmp/apc.XXXXXX ;mbstring mbstring.language = Japanese mbstring.internal_encoding = UTF-8 mbstring.http_input = UTF-8 mbstring.http_output = pass mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
設定を行ったところでhttpd+phpを起動し、PHP7が動作しているか確認します。
# service httpd start httpd を起動中: [ OK ] # /usr/bin/php7/bin/php -v PHP 7.0.5 (cli) (built: Apr 4 2016 12:53:11) ( NTS ) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
9.最適化ビルドされたPHP7の速度を計ってみる
ApacheBenchを実行し最適化PHP7+OPcache+APCuの性能を試してみます。条件は以前の検証環境と同じです。
# ab -n 100 -c 10 https://localhost/ Time taken for tests: 2.629 seconds Requests per second: 38.04 [#/sec] (mean) Time per request: 262.877 [ms] (mean) Time per request: 26.288 [ms] (mean, across all concurrent requests) Transfer rate: 391.96 [Kbytes/sec] received
remiレポジトリのPHP7が30.13/sでしたので、ざっくり25~30%ほど高速化していますね。
もし10/程度しか出ていない場合はOPcacheがエラーになっているはずです。原因はおそらくSElinux。/var/log/httpd/error_logをのぞいてみるとこんなエラーが出ていると思います。
# cat /var/log/httpd/error_log | grep opcache --省略-- Failed loading /usr/bin/php7/lib/php/extensions/no-debug-non-zts-20151012/opcach e.so: /usr/bin/php7/lib/php/extensions/no-debug-non-zts-20151012/opcache.so: ca nnot restore segment prot after reloc: Permission denied --省略-- # getenforce Enforcing # setenforce 0 # getenforce Permissive # service httpd restart httpd を停止中: [ OK ] httpd を起動中: [ OK ]
これで解決した場合は、次のコマンドでSElinuxのラベル付けを行えば解決するはず。
# chcon -v -R -u system_u -r object_r -t textrel_shlib_t /usr/bin/php7/lib/php/extensions/no-debug-non-zts-20151012/opcache.so changing security context of `/usr/bin/php7/lib/php/extensions/no-debug-non-zts-20151012/opcache.so' # setenforce 1 # getenforce Enforcing # service httpd restart httpd を停止中: [ OK ] httpd を起動中: [ OK ]
10.終わりに
以上で、PHP7のコンパイル手順は完了です。記事ではアッサリ説明が終わっていますが、OPcacheが効かない、APCuを入れたのに001 Prime Strategy Translate AcceleratorでAPCキャッシュモードを利用できないなど結構苦労しました。次回はremiレポジトリのPHP7と最適化されたPHP7の速度比較を予定しています。