Dodge the thundering herd with file-based Opcache in PHP7
In the last blog post about Fine-Tuning Opcache Configuration I mentioned the thundering herd problem that affects Opcache during cache restarts.
When Opcache is restarted, either automatically or manually, all current users will attempt to regenerate the cache entries. Under load this can lead to a burst in CPU usage and significantly slower requests.
In PHP5 you can only avoid this by using a rolling deployment, taking each PHP-FPM from the loadbalancer, restarting the cache and then taking it back into the loadbalancer. This isn’t exactly easy to setup and maintain from an ops perspective.
In Rasmus talk at FrOsCon 2015 (Video at 12:30, Slides), he showed the persistent secondary file-based cache Opcache gets in PHP 7. It can read the generated opcodes from disk instead of having to recompile the code after cache restart. This happens only when the compiled opcaches are not found in shared memory.
A persistent cache can fix the problems for high traffic sites that experience thundering herds during deployments and allows new deployment patterns that can avoid restarting php-fpm or Opcache directly.
Rasmus also mentions the benefits for CLI scripts, which can now benefit from Opcache the same way that web-based script execution does.
One downside of a file-based opcache are the additional security implications: Since the webserver can now write files that are executable, care must be taken that an attacker cannot write files into the cache directory.
For now the file cache has to be explictly compiled into PHP 7 using the compile flag
--enable-opcache-file. Afterwards you can control the behavior with three new ini settings:
opcache.file_cache=/var/tmp/php/opcache opcache.file_cache_only=1 # Useful for CLI opcache.file_cache_consistency_checks=1 # Adler checksum
Because Opcache hooks into the most internal parts of the PHP Zend Engine it would probably help if more people tested this new feature on their applications. If you are checking for PHP 7 compatibility, then don’t forget to compile with
--enable-opcache --enable-opcache-file and enable this option as well.
PHP 7 is currently scheduled for release in October, only two months left for testing. Grab Release Candidate 1 from the php.net website if you want to test.