最後更新: 2023-02-14
介紹
package: php56-opcache
This extension OPcache is bundled with PHP 5.5.0 and later, and available in PECL for PHP versions 5.2, 5.3 and 5.4.
ZendOpcache(http://pecl.php.net/package/ZendOpcache)
目錄
- Checking
- Recommended Settings
- Configure
- file_cache
- Opcache GUI
- optimization_level
- My Configure
- Interned Strings
- Troubleshoot
- Doc
Checking
php -r 'phpinfo();' | grep opcache.enable
opcache.enable => On => On opcache.enable_cli => On => On opcache.enable_file_override => Off => Off
Recommended Settings
php.ini
opcache.enable=1 opcache.enable_cli=0 opcache.memory_consumption=96 opcache.interned_strings_buffer=10 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1
Notes:
* Zend OPcache works exclusively with Apache or FastCGI environments (no CLI or CGI support).
* PHP-FPM and FastCGI are mutually exclusive in PHP 5.6
FastCGI (mod_fcgi)
--enable-fpm
--enable-cgi
Standard OPcache already supports php-fpm and php-cgi (with a functional SMA so long as it build with --enable-fastcgi and ran with PHP_FCGI_CHILDREN is > 0. However these solutions don't scale to the typical shared-hosting infrastructure templates where thousands of vhosts are typically configured per server.
Lets first explore how mod_fcgid works:
When request comes in for PHP, mod_fcgid checks if there is idle php process available for that user. If there is none, it starts a new one (up to FCGIDMaxProcessesPerClass, default 100). The request is served, and php process becomes idle. Until next request comes in.
Lets now add opcode caching, like eAccelerator, APC or xCache. Opcode caching software saves opcode (php pre-compiled into "operation code" ) into shared memory. Next time it has to process same PHP file, PHP process would not compile php, using opcode from cache instead.That will significantly decreasing CPU usage, and improving performance.
PHP processes with opcode cache enabled use shared memory for opcode caching. Yet, PHP processes will be able to "share" that shared memory, only if they were all created (forked) from the same, original PHP process, that allocated that shared memory.
This is not the case with mod_fcgid, as each and every PHP process is started by mod_fcgid itself. As the result, they don't "share" shared memory. In this case. each PHP process has its own shared memory, amd no opcode is shared between processes.
So, if process A is responding for request for index.php, and process B is responding to request for index.php, each of them will store its own copy of opcode in its own cache.
Yet, on the second request for index.php to process A, that process can use cached opcode. Gven that single PHP process can process thousands of requests -- opcode caching is useful with mod_fcgid.
Yet, it basically means that each and every PHP process will maintain its own copy of opcode cache. And if you have 1000 php processes, with 256MB of shared memory set for opcode caching -- you are looking at ~256GB of RAM -- that might be in use (though probably most sites will not need to use all 256MB of RAM).
As the result -- it is not practical in shared hosting with mod_fcgid to allocate 256MB shared memory for opcache. Something like 8MB or 4MB would be much more practical.
Another thing to keep in mind is that shared memory size of opcode cache cannot be more then memory_limit in php.ini, as that value controls shared memory size as well.
Configure
/etc/php.d/10-opcache.ini
; RAM you are willing to dedicate to storing opcode.(megabytes)
opcache.memory_consumption=64
; number of scripts that can be cached
opcache.max_accelerated_files=4000
; This configuration directive is ignored if opcache.validate_timestamps is disabled.
; 0 = disabled
opcache.validate_timestamps=0
; how often to check script timestamp for updates (seconds)
; "0" means always validate(on every request)
; This configuration directive is ignored if opcache.validate_timestamps is disabled.
opcache.revalidate_freq=2
; The amount of memory used to store interned strings (megabytes)
opcache.interned_strings_buffer=8
; a fast shutdown sequence is used => doesn't free each allocated block,
; but relies on the Zend Engine memory manager to deallocate the entire set
opcache.fast_shutdown=1
; OPcache appends the current working directory to the script key,
; thus eliminating possible collisions between
; files with the same name
opcache.use_cwd=1
; PHPDoc comments are not loaded from SHM
; all PHPDoc comments are dropped from the code to reduce the size
opcache.load_comments=0
; Check the cache checksum each N requests. 0 = disabled
; This should only be enabled when debugging
opcache.consistency_checks=0
; If disabled, existing cached files using the same include_path will be reused.
; Thus, if a file with the same name is elsewhere in the include_path, it won't be found.
opcache.revalidate_path=1
; the names of files that should not be accelerated.
opcache.blacklist_filename=/etc/php.d/opcache*.blacklist
file_cache
Enables and sets the second level cache directory.
This allows PHP to store compiled code both in memory and disk.
The default "" => disables file based caching.
It should improve performance when
- SHM memory is full (then memory gets flushed)
- Server restart
e.g.
opcache.file_cache="/var/lib/php/opcache"
ls /var/lib/php/opcache/ID/home/vhosts/owncloud/public_html/
index.php.bin remote.php.bin ...
Opcache Blacklist
/etc/php.d/10-opcache.ini
opcache.blacklist_filename=/etc/php.d/opcache*.blacklist
/etc/php.d/opcache-default.blacklist
; <- comments ; The filename may be a full path or just a file prefix ; /var/www/x <- /var/www/x* ; Script 被加入 blacklist 的原因 ; 1) Directories that contain auto generated code ; 2) Code that does not work well when accelerated ; 3) Code that triggers an OPcache bug ; i.e. /usr/share/phpmyadmin/ /usr/share/opcache-gui/
Get Statistics
phpinfo
- Cache hits
- Cache misses
- Used memory
- Free memory
- Wasted Memory - bytes of memory used by invalid or outdated code
Zend OpCache has a setting that will cause the restart of your OpCache if the wasted memory exceeds a threshold.
(opcache.max_wasted_percentage)
- Interned strings usage
if you have the string "foobar" 1000 times in your code,
internally PHP will store 1 immutable variable for this string and just use a pointer to it for the other 999 times you use it.
opcache-gui by amnuts
- support php7
- real-time updates (refresh_time) <- React javascript library
- All the files currently in the cache
- Reset cache (allow_reset / allow_invalidate)
HomePage: https://github.com/amnuts/opcache-gui
有用資訊
opcache statistics
number of cached files: 2,086 number of hits: 67,399 number of misses: 2,086 blacklist misses: 4 # 由於 opcache-gui 了, 所以每次 refress 都會 miss number of cached keys: 3,372 max cached keys: 16,229
interned strings usage
buffer size: 12.00MB
used memory: 8.60MB
free memory: 3.40MB
number of strings: 139,799
Opcache GUI
Download & Install
mkdir /usr/share/opcache-gui
cd /usr/share/opcache-gui
wget https://raw.github.com/amnuts/opcache-gui/master/index.php
vim /etc/httpd/conf.d/opcache-gui.conf
Alias /opcache-gui /usr/share/opcache-gui <Directory /usr/share/opcache-gui> Require ip R.R.R.R Options -Indexes AllowOverride None # php74 <FilesMatch ".+\.php$"> SetHandler application/x-httpd-php SetHandler "proxy:fcgi://127.0.0.1:9074" </FilesMatch> </Directory>
systemctl reload httpd
echo '/usr/share/opcache-gui' >> /etc/opt/remi/php74/php.d/opcache-default.blacklist
systemctl restart php74-php-fpm
optimization_level
# Default: 0x7FFFBFFF
opcache.optimization_level=0xffffffff
設定值 = 要 "+" 所有要開啟的值
參考: https://github.com/zendtech/ZendOptimizerPlus/blob/master/Optimizer/zend...
pass 1 ~ pass 10
Value
- CSE, STRING construction [1]
- Constant conversion and jumps [2]
- ++, +=, series of jumps [4]
- INIT_FCALL_BY_NAME -> DO_FCALL [8]
- ...
My Configure
opcache.enable_cli=1 # fpm 要它 opcache.memory_consumption=64 opcache.max_accelerated_files=4000 opcache.validate_timestamps=1 opcache.revalidate_freq=30 opcache.interned_strings_buffer=8 opcache.fast_shutdown=1 opcache.use_cwd bool=1 opcache.revalidate_path=1 opcache.consistency_checks=0 opcache.save_comments=0
Interned Strings
; The amount of memory for "interned strings" in Mbytes. opcache.interned_strings_buffer=8
Troubleshoot
1) CDN Failed
V2
grep cdn.jsdelivr.net index.php
<script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script> <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script> <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js"></script>
Fix
wget cdn.jsdelivr.net/react/15.4.2/react.min.js
wget cdn.jsdelivr.net/react/15.4.2/react-dom.min.js
wget cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js
修改 index.php
Doc
http://php.net/manual/en/opcache.configuration.php