繼Zend Optimizer 後的 Zend Opcache - 性能優異的PHP 5.5 緩存變化插件 - Opcache配置實用說明
Zend Optimizer(以下簡稱ZO)用優化代碼的方法來提髙php應用程序的執行速度。實現的原理是對那些在被至終執行之前由運行編譯器(Run-Time Compiler)産生的代碼進行優化。
優化能提髙妳的盈利能力
一般情況下,執行使用ZO的php程序比不使用的要快40%到100%。這意味着網站的訪問者可以更快的浏覽網頁,從而完成更多的事務,創造更好的客戶滿意[1] 度。更快的反應同時也意味着可以節省硬件投資,並增強網站所提供的服務。所以,使用ZO,就等於提髙瞭電子商務的盈利能力。
ZO能給php用戶帶來很多益處,特别是那些運營網站的人。快速運行php程序可以顯著降低服務器的CpU負載,並可以減少一半的反應時間,也就是從訪問者點擊鏈接到服務器開始讀取頁麵之間的時間。
的確,用於PHP4的標準運行編譯器已經夠快瞭--相同情況下比PHP3要快2-10倍。但使用瞭ZO的PHP程序的執行速度還會加快40%到100%。
當php的代碼被Zend Guard加密過後,必須安裝解密軟件Zend Optimizer才能進行使用。比如Shopex,Shopnc。
現在很多PHP程序都需要ZendOptimizer環境,但是ZendOptimizer在PHP5.2之後已經被支持,那怎麽辦,Zend也不會這麽做,原來PHP5.3開始ZendOptimizer正式改爲Zend Guard Loader。
Zend Opcache - 新一代PHP變化器,由Zend公司研發,其實現原理與Xcache類似,都是把PHP執行後的數據緩沖到内存中從而避免重複的編譯過程,能夠直接使用緩沖區已編譯的代碼從而提髙速度,降低服務器負載,但性能卻比Xcache更加優越,詳見下方測試結果圖。其機理簡單點說就是將php腳本在虛擬機(暫且稱php至終的機器碼執行引擎爲虛擬機吧)中的機器碼或相應的服務器能夠直接運行的代碼給緩存起來,等到用戶下次請求該腳本時就略過瞭php腳本代碼轉換爲機器碼的過程,從而達到變化php運行、起到緩存的效果。
Optimizer+ 是 Zend 開發的閉源但可以通用使用的 PHP 優化變化組件,是第一個也是至快的 opcode 緩存工具。現在,Zend 科技公司將 Optimizer+ 在 PHP License 下開源成爲 Zend Opcache。
GitHub地址 : https://github.com/zendtech/ZendOptimizerPlus
Zend OPcache 通過 opcode 緩存和優化提供更快的 PHP 執行過程。它將預編譯的腳本文件存儲在共享内存中供以後使用,從而避免瞭從磁盤讀取代碼並進行編譯的時間消耗。同時,它還應用瞭一些代碼優化模式,使得代碼執行更快。
一、什麽是 opcode 緩存?
當解釋器完成對腳本代碼的分析後,便將它們生成可以直接運行的中間代碼,也稱爲操作碼(Operate Code,opcode)。Opcode cache 的目地是避免重複編譯,減少 CPU 和内存開銷。如果動態内容的性能瓶頸不在於 CPU 和内存,而在於 I/O 操作,比如數據庫查詢帶來的磁盤 I/O 開銷,那麽 opcode cache 的性能提昇是非常有限的。但是既然 opcode cache 能帶來 CPU 和内存開銷的降低,這總歸是好事 —— 本着環保的態度,也應該盡量減少消耗不是? :D
現代操作碼緩存器(Optimizer+,APC2.0+,其他)使用共享内存進行存儲,並且可以直接從中執行文件,而不用在執行前“反序列化”代碼。這將帶來顯着的性能變化,通常降低瞭整體服務器的内存消耗,而且很少有缺點。
二、Optimizer+ 與 APC 的優缺點對比
Optimizer+ 於 2013年3月中旬 改名 爲 Opcache。
根據 PHP wiki 上的 討論 ,Zend Opcache 即將整闔到 php 5.5 中。作爲 APC 的競爭對手,新生的 Zend Opcache 很有可能取代 APC 的位置,雖然 OptimizerPlus 沒有象 APC 那樣的 user cache 功能。
OPTIMIZER+ 相對 APC 的優點
1、性能。根據測試,Zend Optimizer+ 始終優於 APC。隨代碼差異,每秒鍾處理的請求數髙 5~20%。Google doc 上記錄的 測試結果 中,WordPress 2.1.1(不知道爲什麽不用個新版本的 WP 來測試),性能提髙約 8%。理論上來說,對於 WP 3.5.1,性能應該也能得到大約 5~10% 的提昇吧。對於運行 WordPress 的服務器而言,使用 Optimizer+ 可以顯著降低 CPU 使用率和提髙頁麵加載速度( graphics here )。
2、支持新的 PHP 版本。Zend 和 PHP 社區都會幫助 Optimizer+ 能夠支持至新版本的 PHP。
3、可靠性。Optimizer+ 擁有可選的損壞檢測能力,可以防止因數據損壞而導緻的服務器崩潰。
4、更好的兼容性。PHP 社區打算讓 Optimizer+ 與社區支持的所有 PHP 版本相兼容
APC 相對 OPTIMIZER+ 的優勢
1、APC 有數據緩存 API,而 Optimizer+ 沒有。
2、APC 能夠回收舊的無效的腳本佔用的内存。APC 有内存管理器,可以將那些不再使用的腳本關聯的内存進行回收。而 Optimizer+ 不同,它將這樣的内存標記爲“髒的”,但並不會回收它們。一旦“髒的”内存佔用配置阈值的百分比達到一定值,Optimizer+ 就將自己重新啓動。這種行爲在穩定性上既有優勢也有劣勢。
三、使用 Zend Opcode
現在已經可以使用 Zend Opcache 替代 APC 作爲 PHP 優化變化工具瞭。目前的 Zend Opcode 兼容 PHP 5.2.*、5.3.*、5.4.* 和 PHP-5.5 開發版。不過,將來會取消對 PHP 5.2 的支持。
註意: Zend Opcache 與 eaccelerator 相沖突。要安裝 Zend Opcache,可能需要先卸載 eaccelerator —— 如果妳用瞭這個變化模塊的話。
編譯安裝 Zend Opcache
#分享源代碼 ( wget -c 代碼地址)
https://github.com/zendtech/ZendOptimizerPlus/archive/master.zip
#切換解壓後的源碼目錄,利用phpize執行安裝
cd /usr/local/src/ZendOptimizerPlus-master
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config#編輯 php.ini ,追加如下内容:
zend_extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/opcache.so
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1opcache相關參數,可參考:
GitHub : https://github.com/zendtech/ZendOptimizerPlus
上述github頁麵中,有個推薦配置:
We recommend the following configuration options for best performancein a production environment.
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
PHP手冊 : http://php.net/manual/zh/opcache.configuration.php
啓用opcache後的一些情況
典型的就是由於opcache的緩存變化機製導緻的代碼變更後無法立即看到效果。php代碼被轉換成可立即執行的“機器碼”後會有一定的緩存時間後才會去檢查原始的PHP文件是否變動過,具體視配置項opcache.revalidate_freq設置的秒數情況而定;這樣就會導緻某些情況下明明更新瞭PHP文件中的代碼,但執行後卻看不到改變後的效果,這就是因爲opcache檢查php文件變動的間隔時間尚未結束所導緻。
這個問題並不是bug,而要視具體生産環境來設定opcache.revalidate_freq值,倘若php代碼很少變動,建議該值設置的大一些,可減少opcahce由於檢查php文件變動而帶來的額外開銷,比如7200
那麽在變動php文件後如何才能快速降低opcache緩存帶來的這種問題呢?至簡單的方法就是更新代碼後重啓下php-fpm(nginx fast-cgi模式)或apache(apache-handler模式)。當然還可以自己書寫一個php腳本,調用opcache_reset()函數重置所有opcache緩存字節碼,或者使用opcache_invalidate(PHPfileDir,true)重置指定php文件的緩存字節碼。
PHP 上有不少 opcode cache 組件,如 APC、eAccelerator、XCache 等。(參見 Wikipedia 上的 PHP accelerators 列錶。)看 PHP wiki 上的意思,這個新引入的 Zend Opcache 的性能應該是至好的。
以下是opcache的配置說明:
複製代碼
[opcache]
zend_extension = "G:/PHP/php-5.5.6-Win32-VC11-x64/ext/php_opcache.dll"
; Zend Optimizer + 的開關, 關閉時代碼不再優化.
opcache.enable=1
; Determines if Zend OPCache is enabled for the CLI version of PHP
opcache.enable_cli=1
; Zend Optimizer + 共享内存的大小, 總共能夠存儲多少預編譯的 PHP 代碼(單位:MB)
; 推薦 128
opcache.memory_consumption=64
; Zend Optimizer + 暫存池中字符串的佔内存總量.(單位:MB)
; 推薦 8
opcache.interned_strings_buffer=4
; 至大緩存的文件數目 200 到 100000 之間
; 推薦 4000
opcache.max_accelerated_files=2000
; 内存“浪費”達到此值對應的百分比,就會發起一個重啓調度.
opcache.max_wasted_percentage=5
; 開啓這條指令, Zend Optimizer + 會自動將當前工作目錄的名字追加到腳本鍵上,
; 以此消除同名文件間的鍵值命名沖突.關閉這條指令會提昇性能,
; 但是會對已存在的應用造成破壞.
opcache.use_cwd=0
; 開啓文件時間戳驗證
opcache.validate_timestamps=1
; 2s檢查一次文件更新 註意:0是一直檢查不是關閉
; 推薦 60
opcache.revalidate_freq=2
; 允許或禁止在 include_path 中進行文件搜索的優化
;opcache.revalidate_path=0
; 是否保存文件/函數的註釋 如果apigen、Doctrine、 ZF2、 PHPUnit需要文件註釋
; 推薦 0
opcache.save_comments=1
; 是否加載文件/函數的註釋
;opcache.load_comments=1
; 打開快速關閉, 打開這個在PHP Request Shutdown的時候會收内存的速度會提髙
; 推薦 1
opcache.fast_shutdown=1
;允許複蓋文件存在(file_exists等)的優化特性。
;opcache.enable_file_override=0
; 定義啓動多少個優化過程
;opcache.optimization_level=0xffffffff
; 啓用此Hack可以暫時性的解決”can’t redeclare class”錯誤.
;opcache.inherited_hack=1
; 啓用此Hack可以暫時性的解決”can’t redeclare class”錯誤.
;opcache.dups_fix=0
; 設置不緩存的黑列單
; 不緩存指定目錄下cache_開頭的PHP文件. /png/www/example.com/public_html/cache/cache_
;opcache.blacklist_filename=
; 通過文件大小屏除大文件的緩存.默認情況下所有的文件都會被緩存.
;opcache.max_file_size=0
; 每 N 次請求檢查一次緩存校驗.默認值0錶示檢查被禁用瞭.
; 由於計算校驗值有損性能,這個指令應當緊緊在開發調試的時候開啓.
;opcache.consistency_checks=0
; 從緩存不被訪問後,等待多镹後(單位爲秒)調度重啓
;opcache.force_restart_timeout=180
; 錯誤日誌文件名.留空錶示使用標準錯誤輸出(stderr).
;opcache.error_log=
; 將錯誤信息寫入到服務器(Apache等)日誌
;opcache.log_verbosity_level=1
; 内存共享的首選後臺.留空則是讓係統選擇.
;opcache.preferred_memory_model=
; 防止共享内存在腳本執行期間被意外寫入, 僅用於内部調試.
;opcache.protect_memory=0