Yoopee cache (op cache internals)

67 %
33 %
Information about Yoopee cache (op cache internals)

Published on February 22, 2014

Author: jpauli



YooopeeCache PHP OPCache explained

Hello everybody  Julien PAULI  Programming in PHP since ~10y  PHP Internals reviewer since ~3y  PHP 5.5 and 5.6 Release Manager  Working at SensioLabs in Paris   @julienpauli - -

What we'll cover together  Reminder on how PHP works  Introduction to OPCodes  The need of an OPCode cache  OPCache in deep  OPCache configuration settings  Benchmarks

What is PHP ?  PHP  Programming language  "Scripting language"  No *manual* compilation needed  Fire and forget     Automatic memory management No strong typing Provides OOP features Highly dynamic, highly extensible

How does PHP work ? Result Executing opcodes Compiling nodes Parsing (Lexer + parser) PHP code

Zend Virtual Machine  "VirtualMachine"  Its purpose is to provide a platformindependent programming environment that abstracts away details of the underlying hardware or operating system, and allows a program to execute in the same way on any platform (Wikipedia) Executing Compiling Parsing (Lexer + parser)

The PHP way  Compile, execute, forget - Compile, execute, forget Compile, execute, forget - Compile, execute, forget Compile, execute, forget - Compile, execute, forget Compile, execute, forget - Compile, execute, forget …  By default (by design), PHP discards all the code it just executed  Request n+1 knows nothing about request n

The PHP Way  If your pages get hit several times without changing (most likely)  → compile the same scripts several times  → it still produces the same OPCodes Compiling Parsing (Lexer + parser)

Compiling VS Executing  Compile, then execute  Which one is the longest ?  Depends on your scripts Execute Execute Compile Compile

Compiling VS Executing  Compilation can really take time  Usually less than execution, but...

Understanding compil. / exec.  Classes usually require much more compile time than exec time  include / require / eval() = compile + execute  autoload = compile + execute  .. deffered at execution B Compile Execute E Y include/require ? eval() ? autoload ? N

OPCode cache roles Result Executing opcodes Caching opcodes Compiling nodes Parsing (Lexer + parser) PHP code

opcodes Save at first run Shared Memory Executing opcodes Caching save opcodes Compiling nodes

opcodes Load (same script) after Executing opcodes Shared Memory load OPCode cache PHP code

Optimize  Why not optimize the OPCode array ? Executing opcodes Shared Memory save Caching opcodes opcodes Optimizing opcodes Compiling

PHP OPCache OPCodes explained

OPCode  In computer science, an opcode (operation code) is the portion of a machine language instruction that specifies the operation to be performed. (Wikipedia)  Opcodes can also be found in so called byte codes and other representations intended for a software interpreter rather than a hardware device. (Wikipedia)

Zend OPCodes

Example of OPCode <?php const DEF = "default"; if (isset($argv[1])) { $b = (array)$argv[1]; } else { $b = DEF; } var_dump($b);

Example of OPCode <?php const DEF = "default"; if (isset($argv[1])) { $b = (array)$argv[1]; } else { $b = DEF; } var_dump($b);

Example of OPCode if (isset($argv[1])) { $b = (array)$argv[1]; } else { $b = DEF; } Compilation Execution <?php const DEF = "default"; var_dump($b);  The more code to parse, the longer the compilation phase  The more OPCodes generated, the longer the execution (usually)

Optimize compilation  "The more code to parse, the longer the compilation phase" opcodes  No problem : OPCode caches compile any script just once Executing opcodes Shared Memory load OPCode cache PHP code

Optimize execution  "The more OPCodes generated, the longer the execution (usually)" Executing  Some OPCodes are heavier than others  OPCodes may be run several times (in fact, yes they do)  The optimizer can play a role Caching Optimizing Compiling

OPCache  "OPCache" is the default PHP OPCode cache  It is available for 5.3, 5.4 and 5.5  Bundled in the 5.5 distribution  PECL for others  It is both a cache, and an optimizer

Optimizer  Tries to simplify/optimize the OPCodes so that there are less of them and they are more efficient     Works on code branches (if, switch, try …) Optimize constant expressions Look for dead code Look for ways to reuse things  Examples :

Optimizer in action if (false) { echo "foo"; } else { echo "bar"; } Classic compilation : Optimized compilation :

Optimizer in action $a = 4 + "33"; echo $a; Classic compilation : Optimized compilation :

Optimizer in action  Can you get the trick ? $a = 8; $c = $a + "42"; echo $c; Classic compilation : Optimized compilation :

Optimizer in action $i = "foo"; $i = $i + 42; echo $i; Classic compilation : Optimized compilation :

Optimizer in action $j = 4; $j++; echo $j; Classic compilation : Optimized compilation :

Optimizer in action Classic compilation : Optimized compilation : $a = $_GET['a'] + 7; $b = $_GET['a'] - 18;

Optimizer in action const FOO = "bar"; echo FOO; Classic compilation : Optimized compilation :

More optimizations  This was the visible part  OPCache takes care of lots more invisible optimizations 

Interned strings optimized  In computer science, string interning is a method of storing only one copy of each distinct string value, which must be immutable. Interning strings makes some string processing tasks more time- or space-efficient at the cost of requiring more time when the string is created or interned. The distinct values are stored in a string intern pool Wikipedia

Interned strings concept  Anytime a static string occurs in compiler, memorize it, and reuse its pointer when needed. class foo { public function bar($a = "foo") { } } $foo = new foo; $foo->bar("foo");  Interned strings have been added to PHP5.4 compiler  OPCache optimizes them even more

Interned strings before 5.4  Before 5.4, the compiler allocated memory for each string it met, whatever it was class foo { public function bar($a = "foo") { } } $foo = new foo; $foo->bar("foo"); foo bar a foo foo foo memory foo bar foo

Interned strings with >=5.4  Starting from 5.4, the compiler allocates memory for strings and reuse the pointer if it meets the same string later class foo { public function bar($a = "foo") { } } $foo = new foo; $foo->bar("foo"); foo bar a memory

Interned strings optimizations  When strings are interned, they no longer need to be duplicated static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */ { if (!IS_INTERNED(property_info->name)) { property_info->name = estrndup(property_info->name, property_info->name_length); } if (property_info->doc_comment) { property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len); } }  Every hash of hashtable is precomputed if (IS_INTERNED(Z_STRVAL_P(varname))) { hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); }

OPCache & interned strings  OPCache interns strings from all PHP processes of the same PHP pool  Nice memory savings on big pools interned string mem interned string mem interned string mem interned string mem

PHP OPCache OPCache API, settings and tuning

OPCache API  opcache_reset()  Resets the whole cache, invalidates all files  opcache_invalidate($file)  Invalidates a single file  opcache_get_configuration()  returns current INI settings  opcache_get_status()  returns an array of internal stats  opcache_compile_file()  Compile a single file into the cache at runtime

OPCache frontend 

OPCache settings  memory_consumption (=64M)  Size of Shared Memory  Don't forget to increase if needed  For example, a "classical" Symfony2 app needs ~40Mb  Buy more RAM, NEVER have a cache full, have margin  max_accelerated_files (=2000)     Max number of KEYS to be stored Aligned at next prime number Slots are preallocated : don't give too high number A "classical" Symfony2 app needs ~3000

OPCache explained  memory_consumption=128M  max_accelerated_files = 3000  Next prime : 3907  Cached files : 1877  Cached keys : 2722 / 3907

How OPCache computes keys ?  A file "Foo" may be accessed in your script  With a full path (/path/to/foo.php)  With many relative paths (../../foo.php)  Which then all have to be resolved  OPCache makes the slots' keys with all the met paths to a file  This prevents it from calling realpath() too often  This occupies "slots"  Typically, an average is ~3 slots per file  If you play with symlinks, mind php realpath_cache_ttl setting

How OPCache computes keys ? require "/full/path/to/foo.php" key 1 require "../relativepath/to/foo.php" key 2 require "./relativepath/../to/foo.php" key 3 max_accelerated_files Foo script

OPCache settings  validate_timestamps (=true)  Check for file update to invalidate it  Checks are triggered every revalidate_freq seconds  revalidate_freq (=2)  How often check for file updates to invalidate them  Try not to put 0, meaning every time  Revalidate often use syscall fstat()  But SAPI stat cache is used, thus preventing a stat call  max_wasted_percentage (=5)  Percentage threshold to trigger an opcache reset

OPCache memory details  When a script changes, it is recompiled (if validate_timestamps = 1)  Its old memory space is then considered as "wasted" (it is then NOT freed)  When cache is full, if max_wasted_percentage is reached : a cache restart is triggered  Cache restart = empty cache and recompile all  Cache is never restarted if not full

OPCache restarts  This cache is full , but current_wasted_percentage < max_wasted_percentage  So the cache will not restart yet  restart_pending = restart_in_progress = false

OPCache restart reasons  oom_restarts  Cannot allocate memory for keys of for script space  Your memory segment is too small, increase memory_consumption  hash_restarts  One hashtable is full and needs more slots  You reached the max num of keys, increase max_accelerated_files  manual_restarts  You used opcache_reset()

Know what happens  error_log (=stderr)  File to write log to  log_verbosity_level (=1)  0=fatals … 4=debug

OPcache other settings  optimization_level (=0xffffffff)  Enable/disable some optimizations. Recommanded : all  fast_shutdown (=0)  Changes the RShutdown sequence with an optimized one : recommanded  enable_file_override (=1)  Redefines file_exists(), is_readable() and is_file() to look into cache before : recommanded  blacklist_filename (=NULL)  Prevents caching some files you decide  consistency_checks (=0)  Computes a checksum at each file fetch. Not recommanded, ~5-8% slowdown

OPCache do's and don't's  Prime your cache smoothly   Prevent cache stampede  Have enough shared memory  Size your hashtables correctly  Try not to generate php files on runtime  Prevent highly modified files from beeing cached  Use blacklists  Every cache action will lock the shared memory  And PHP Engine is not threaded

Thank you for listening

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

Дайджест интересных новостей и материалов из мира PHP № 36 ...

Идеи для PHP 6 — Тем временем в php.internals активным образом ... Yoopee cache (op cache internals) ...
Read more

php internals - Does PHP interpreter compiles to bytecode ...

... PHP interpreter compiles to bytecode every command and ... the opcode cache) - See ... php php-internals or ...
Read more

GitHub - clem/sflive-paris-2014: Les différentes ... Lien vers la vidéo. Du SSO via OAuth pour mieux découpler votre application.
Read more

On PHP function calls (PHP 5) - GitHub Pages

A conclusion on PHP function calls ?# ... you may fetch my slides at for example. ...
Read more