NFS架構(gòu)下使用realpath_turbo優(yōu)化php性能

PHP進(jìn)程調(diào)試中出現(xiàn)大量lstat系統(tǒng)調(diào)用,通過編譯realpath_turbo模塊,開啟同時支持open_basedir和realpath_cache_size,優(yōu)化php性能

生產(chǎn)系統(tǒng)架構(gòu)

程序和數(shù)據(jù)大概500G,存放在一臺ECS上,開啟了NFS共享給若干臺Nginx服務(wù)器進(jìn)行讀寫,包括共享session也存于NFS分區(qū)。數(shù)據(jù)下一步準(zhǔn)備遷移到OSS.

在系統(tǒng)運(yùn)行中發(fā)現(xiàn)NFS的讀寫效率較低,調(diào)節(jié)NFS的緩存參數(shù)也無改善。例如通過記錄php慢日志,看到大量session_start執(zhí)行很慢:

于是將session存儲方式由文件改為redis,得以解決。

在google搜索NFS+session_start的過程中,發(fā)現(xiàn)了一篇老外的神貼:

http://php.webtutor.pl/en/2011/06/02/running-php-on-nfs-huge-performance-problems-and-one-simple-solution/

文中提到了在NFS下面php的性能問題:由于php程序中需要使用大量的require和include,導(dǎo)致出現(xiàn)大量lstat系統(tǒng)調(diào)用,大大降低程序性能。雖然沒有明確闡述,但我理解,NFS下這個問題會比較明顯。立即在生產(chǎn)系統(tǒng)中采用strace命令進(jìn)行統(tǒng)計分析:

#通過strace跟蹤php-fpm詳細(xì)的lstat調(diào)用規(guī)律#pgrep用法:#-n匹配最新(最近生成的)符合所有其它匹配條件的進(jìn)程#-o匹配最舊(最早生成的)符合所有其它匹配條件的進(jìn)程

strace -c -p $(pgrep -n php-fpm)

果然看到 lstat 占比排第一(由于現(xiàn)在生產(chǎn)系統(tǒng)已經(jīng)調(diào)優(yōu),無法再捕獲結(jié)果,參考上述文檔)

通常調(diào)優(yōu)這個問題可以通過在php.ini(或php-fpm.conf)修改realpath_cache_size和realpath_cache_ttl這兩個參數(shù)即可:

realpath_cache_size: php進(jìn)程所使用的真實(shí)路徑緩沖區(qū)的大小,默認(rèn)16K

realpath_cache_ttl: 緩存時間,默認(rèn)120秒

將以上兩個參數(shù)適當(dāng)加大,即可減少lstat的調(diào)用次數(shù)。

但是當(dāng)php設(shè)置了open_basedir或者開啟了safe_mode時,這兩個參數(shù)將不再生效,見http://bugs.php.net/bug.php?id=52312

open_basedir的作用是限制php的讀取目錄,是必要的安全設(shè)置,當(dāng)然不能取消。要想同時開啟二者,就要引入大神的realpath_turbo模塊了。github地址:https://github.com/Whissi/realpath_turbo

編譯安裝:

cd ~wgethttps://github.com/Whissi/realpath_turbo/archive/master.zip -O realpath_turbo.zipunzip realpath_turbo.zip cd realpath_turbo-master//usr/local/php_5.3.29/bin/phpize ./configure --with-php-config=/usr/local/php_5.3.29/bin/php-config makemake test NO_INTERACTION=1make installecho extension=realpath_turbo.so >> /usr/local/php_5.3.29/lib/php.ini

中間遇到一個編譯錯誤:

/root/realpath_turbo-master/realpath_turbo.c: In function ‘zm_activate_realpath_turbo’:/root/realpath_turbo-master/realpath_turbo.c:43:warning: initialization makes pointer from integer without a cast/root/realpath_turbo-master/realpath_turbo.c:76:error: invalid type argument of ‘unary *’ (have ‘int’)make: *** [realpath_turbo.lo] Error1

打開realpath_turbo.c,去掉74-83行,這段是判斷是否開了safe_mode,如果開了編譯就不通過。因?yàn)闆]有開safe_mode,直接刪掉。

由于使用了php-fpm,將模塊的配置放到了php-fpm.conf中

php_value[open_basedir] = ""php_value[realpath_turbo.disable_dangerous_functions] = 1php_value[realpath_turbo.open_basedir] = "/home1/wwwroot/public_html:/home1/tmp/:/home1/log/"php_value[realpath_cache_size] = 20mphp_value[realpath_cache_ttl] = 3600

``

重啟php-fpm,在phpinfo中看到realpath_turbo模塊已經(jīng)加載。

再次進(jìn)行strace,可以看到lstat已經(jīng)不在占用最多時間,優(yōu)化完成。

更多PHP相關(guān)技術(shù)請搜索千鋒PHP,做真實(shí)的自己,用良心做教育。

互聯(lián)網(wǎng)+時代,時刻要保持學(xué)習(xí),攜手千鋒PHP,Dream It Possible。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容