閱讀571 返回首頁    go 阿裏雲 go 技術社區[雲棲]


NFS架構下使用realpath_turbo優化php性能

生產係統架構圖
architecture

程序和數據大概500G,存放在一台ECS上,開啟了NFS共享給若幹台Nginx服務器進行讀寫,包括共享session也存於NFS分區。數據下一步準備遷移到OSS.

在係統運行中發現NFS的讀寫效率較低,調節NFS的緩存參數也無改善。例如通過記錄php慢日誌,看到大量session_start執行很慢:
session_start
於是將session存儲方式由文件改為redis,得以解決。

在google搜索NFS+session_start的過程中,發現了一篇老外的神貼:

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

文中提到了在NFS下麵php的性能問題:由於php程序中需要使用大量的require和include,導致出現大量lstat係統調用,大大降低程序性能。雖然沒有明確闡述,但我理解,NFS下這個問題會比較明顯。立即在生產係統中采用strace命令進行統計分析:

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

果然看到 lstat 占比排第一(由於現在生產係統已經調優,無法再捕獲結果,參考上述文檔)

通常調優這個問題可以通過在php.ini(或php-fpm.conf)修改realpath_cache_size和realpath_cache_ttl這兩個參數即可:
realpath_cache

realpath_cache_size: php進程所使用的真實路徑緩衝區的大小,默認16K
realpath_cache_ttl: 緩存時間,默認120秒

將以上兩個參數適當加大,即可減少lstat的調用次數。

但是當php設置了open_basedir或者開啟了safe_mode時,這兩個參數將不再生效,見 https://bugs.php.net/bug.php?id=52312
open_basedir的作用是限製php的讀取目錄,是必要的安全設置,當然不能取消。要想同時開啟二者,就要引入大神的realpath_turbo模塊了。github地址:https://github.com/Whissi/realpath_turbo

編譯安裝:

cd ~
wget https://github.com/Whissi/realpath_turbo/archive/master.zip -O realpath_turbo.zip
unzip 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 
make
make test NO_INTERACTION=1
make install

echo 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] Error 1

打開realpath_turbo.c,去掉74-83行,這段是判斷是否開了safe_mode,如果開了編譯就不通過。因為沒有開safe_mode,直接刪掉。

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

php_value[open_basedir] = ""
php_value[realpath_turbo.disable_dangerous_functions] = 1
php_value[realpath_turbo.open_basedir] = "/home1/wwwroot/public_html:/home1/tmp/:/home1/log/"
php_value[realpath_cache_size] = 20m
php_value[realpath_cache_ttl] = 3600
``
重啟php-fpm,在phpinfo中看到realpath_turbo模塊已經加載。

再次進行strace,可以看到lstat已經不在占用最多時間,優化完成。
![strace2](https://yqfile.alicdn.com/2a3d49fefebf5a456db8262090e39eab80dfc36c.png)

最後更新:2017-05-13 16:01:07

  上一篇:go  【速轉身邊開公司的朋友】連加油站都被比特幣勒索病毒黑了!還沒關閉服務器445端口的抓緊!
  下一篇:go  我的 10 年自學編程之路