Tim Hysniu
Tim Hysniu

Reputation: 1540

PHP Opcache Replacement Strategy

I understand that APC is being replaced by OpCache. I enabled this module and all is working so far. However, there is very little documentation on how to tune this for best performance.

My system currently has a ton of files that need to be cached. So if these files make it to cache then everything is great. However, if the max is reached I have a lot of files that I might not want in cache.

Preferably I would like to cache files that are going to have the highest hit rate. So it would be nice to know what is the replacement strategy that Opcache uses, if at all. How do I solve the problem not having most frequently used files in cache. Any of FIFO, LRU, would work well for my system, but I haven't found any documentation on this yet.

Any help would be appreciated!

Upvotes: 3

Views: 1071

Answers (1)

Jens A. Koch
Jens A. Koch

Reputation: 41796

Replacement Strategy

Don't expect a FIFO or LRU. That thingy doesn't working like that. The Opcode cache stores code on first access to a PHP file, optimizes the code internally and makes the decision, whether to renew files in the cache, based on time intervals and file modification stamp and memory used.

So the key questions: How many files to cache? How much memory for storage? what's with internal code optimizations? How to exclude files? When will it refresh files? If you want to understand the OpCache in depth, you'll find a great writeup by Julien Pauli here: http://jpauli.github.io/2015/03/05/opcache.html

How do I solve the problem not having most frequently used files in cache.

I would increase the memory and max file settings, until these files are cached.

However, if the max is reached I have a lot of files that I might not want in cache.

  • opcache.blacklist_filename to the rescue. You could use a blacklist file to describe which files should not be accelerated.

Important note: You can not trigger a cache removal by using the opcache-invalidate() function. That will just mark an already cached file for recompilation and re-addition to the cache (recompile/refresh). A full removal of files from the cache needs a reset or restart; which always causes a spike.


The OpCache Readme contains the following advise:

Speed Tuning

We recommend the following configuration options for best performance in 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

You also may add the following, but it may break some applications and frameworks. Please, read description of these directives and add them on your own risk.

opcache.save_comments=0 
opcache.enable_file_override=1

There is very little documentation on how to tune this for best performance


Strategy for performance tuning

Finding the optimal settings is based on a lot of things. You can use an A/B or A/B/C testing strategy for finding good values for configuration directives.

Your starting point is an activated OpCache with default settings to run a performance Test A. Then you would tune or tweak some OpCache directives to alter the caching behavior and run performance Test B. Finally, you can compare the results and draw a conclusion, if the changes to directives yield the results you want and improve performance.

Cache warmup

When the cache is empty run a script, which travels the "hot paths" (commonly used paths of your application). That makes sure, the underlying files have cache coverage from the start.

GUI tools

To see the statistics, the files cached and the memory used, you would also use one of the OpCache "inspectors". That gives you an overview and enables you too find files for exclusion from the cache.

Some performance related directives

http://php.net/manual/de/opcache.configuration.php

  • opcache.memory_consumption. Default is 64MB. You could raise it.
  • opcache.max_accelerated_files - maximum number of cached files. To find out the number of files: find . -type f -print | grep php | wc -l.
  • Important is the opcache.optimization_level directive. For details see https://stackoverflow.com/a/21291587/1163786
  • opcache.interned_strings_buffer - The optimizer uses a technique called string interning to improve performance. Which basically means, if your application makes use of the string "Hello World" 100 times, the string would be stores only 1 time, which saves 99 string stores and results in 99 accesses to an already existing value. 4MB is default. Try 8, 12, 16.
  • opcache.validate_timestamps=0 means extra stat calls are removed.
  • opcache.save_comments - Does your application use docblock annotations inside comments? If not, turn off. This saves memory.
  • opcache.load_comments - Comments are either in the cache or not depending on opcache.save_comments. This directive means "do not load cached comments". Seems stuff gets cached, which is never used. I have to admin that i don't get the use case for this directive. In other words: i use opache.save_comments to control the addition of comments.
  • opcache.fast_shutdown - This is a technique to call the deconstructors faster. Turn on.

Upvotes: 5

Related Questions