Yoopee cache (op cache internals)

9 101 vues

Publié le

Publié dans : Technologie
1 commentaire
14 j’aime
Statistiques
Remarques
Aucun téléchargement
Vues
Nombre de vues
9 101
Sur SlideShare
0
Issues des intégrations
0
Intégrations
2 121
Actions
Partages
0
Téléchargements
0
Commentaires
1
J’aime
14
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Yoopee cache (op cache internals)

  1. 1. YooopeeCache PHP 5 OPCache explained
  2. 2. Hello everybody  Julien PAULI  Programming in PHP since ~10y  Programming in C for PHP Internals  PHP 5.5 and 5.6 Release Manager  Working at SensioLabs in Paris  http://www.phpinternalsbook.com  @julienpauli - jpauli.github.io - jpauli@php.net
  3. 3. 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
  4. 4. 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
  5. 5. How does PHP work ? Parsing (Lexer + parser) Compiling Executing opcodes PHP code nodes Result
  6. 6. Zend Virtual Machine Parsing (Lexer + parser) Compiling Executing  "VirtualMachine"  Its purpose is to provide a platform-independent 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)
  7. 7. 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
  8. 8. 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 Parsing (Lexer + parser) Compiling
  9. 9. Compiling VS Executing  Compile, then execute  Which one is the longest ?  Depends on your scripts Compile Execute Execute Compile
  10. 10. Compiling VS Executing  Compilation can really take time  Usually less than execution, but...
  11. 11. Understanding compil. / exec.  Classes usually require much more compile time than exec time  include / require / eval() = compile + execute  autoload = compile + execute  .. deffered at execution Compile Execute include/require ? eval() ? autoload ? B N Y E
  12. 12. OPCode cache roles Parsing (Lexer + parser) Compiling Executing opcodes PHP code nodes Result Caching opcodes
  13. 13. Save at first run Compiling Executing opcodes nodes Caching opcodes Shared Memory opcodes save
  14. 14. Load (same script) after OPCode cache Executing opcodes Shared Memory PHP code opcodes load
  15. 15. Optimize  Why not optimize the OPCode array ? opcodes Optimizing opcodes Shared Memory opcodes Caching Compiling save Executing opcodes
  16. 16. PHP OPCache OPCodes explained
  17. 17. 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)
  18. 18. Zend OPCodes
  19. 19. Example of OPCode <?php const DEF = "default"; if (isset($argv[1])) { $b = (array)$argv[1]; } else { $b = DEF; } var_dump($b);
  20. 20. Example of OPCode <?php const DEF = "default"; if (isset($argv[1])) { $b = (array)$argv[1]; } else { $b = DEF; } var_dump($b);
  21. 21. Example of OPCode <?php const DEF = "default"; if (isset($argv[1])) { $b = (array)$argv[1]; } else { $b = DEF; } var_dump($b); Execution Compilation  The more code to parse, the longer the compilation phase  The more OPCodes generated, the longer the execution (usually)
  22. 22. Optimize execution  "The more OPCodes generated, the longer the execution (usually)"  Some OPCodes are heavier than others  OPCodes may be run several times (in fact, yes they do)  The optimizer can play a role Optimizing Caching Compiling Executing
  23. 23. OPCache  "OPCache" is the default PHP OPCode cache  It is available for 5.3, 5.4, 5.5 and 5.6 (and 7.0)  Bundled in the 5.5 distribution  PECL for others  It is both a cache, and an optimizer
  24. 24. 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 :
  25. 25. Optimizer in action if (false) { echo "foo"; } else { echo "bar"; } Classic compilation : Optimized compilation :
  26. 26. Optimizer in action $a = 4 + "33"; echo $a; Classic compilation : Optimized compilation :
  27. 27. Optimizer in action  Can you get the trick ? $a = 8; $c = $a + "42"; echo $c; Classic compilation : Optimized compilation :
  28. 28. Optimizer in action $i = "foo"; $i = $i + 42; echo $i; Classic compilation : Optimized compilation :
  29. 29. Optimizer in action $j = 4; $j++; echo $j; Classic compilation : Optimized compilation :
  30. 30. Optimizer in action $a = $_GET['a'] + 7; $b = $_GET['a'] - 18; Classic compilation : Optimized compilation :
  31. 31. Optimizer in action const FOO = "bar"; echo FOO; Classic compilation : Optimized compilation :
  32. 32. More optimizations  This was the visible part  OPCache takes care of lots more invisible optimizations  http://en.wikipedia.org/wiki/Category:Compiler_optimi zations
  33. 33. 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
  34. 34. Interned strings concept  Anytime a static string occurs in compiler, memorize it, and reuse its pointer when needed.  Interned strings have been added to PHP5.4 compiler  OPCache optimizes them even more class foo { public function bar($a = "foo") { } } $foo = new foo; $foo->bar("foo");
  35. 35. Interned strings before 5.4 class foo { public function bar($a = "foo") { } } $foo = new foo; $foo->bar("foo");  Before 5.4, the compiler allocated memory for each string it met, whatever it was foo bar a foo foo foo foo bar foo memory
  36. 36. Interned strings with >=5.4 class foo { public function bar($a = "foo") { } } $foo = new foo; $foo->bar("foo");  Starting from 5.4, the compiler allocates memory for strings and reuse the pointer if it meets the same string later foo bar a memory
  37. 37. Interned strings optimizations  When strings are interned, they no longer need to be duplicated  Every hash of hashtable is precomputed 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); } } 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); }
  38. 38. 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
  39. 39. PHP OPCache OPCache API, settings and tuning
  40. 40. 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
  41. 41. OPCache frontend  https://github.com/rlerdorf/opcache- status/blob/master/opcache.php
  42. 42. 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
  43. 43. OPCache explained  memory_consumption=128M  max_accelerated_files = 3000  Next prime : 3907  Cached files : 1878  Cached keys : 2722 / 3907
  44. 44. 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
  45. 45. How OPCache computes keys ? Foo script require "/full/path/to/foo.php" require "../relativepath/to/foo.php" require "./relativepath/../to/foo.php" key 3 key 2 key 1 max_accelerated_files
  46. 46. 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  0 = every time  Revalidate = syscall cached by PHP's realpath cache  revalidate_paths (=0)  1 : only the resolved realpath is used as cache key  0 : the unresolved path is also added as a cache key  use_cwd (=1)  prepend cwd to every cache key for relative paths
  47. 47. 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
  48. 48. OPCache restarts  This cache is full , but current_wasted_percentage(5.07%) < max_wasted_percentage(10%)  So the cache will not restart yet  restart_pending = restart_in_progress = false
  49. 49. 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()
  50. 50. OPCache memory image
  51. 51. Know what happens  error_log (=stderr)  File to write log to  log_verbosity_level (=1)  0=fatals … 4=debug
  52. 52. 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
  53. 53. OPCache do's and don't's  Prime your cache smoothly  https://github.com/engineyard/ey-php-performance-tools  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
  54. 54. APC vs OPCache  APC is dead nowadays  No more commits / debug  Not stable under 5.4 (very latest release are)  Not very tested under 5.5 and 5.6  Not compatible at all with PHP 7  OPCache is faster than APC  Zend's benchmarks did show ~+15% avg  OPCache works everywhere APC does or used to  5.2 -> 5.6
  55. 55. APC vs OPCache  OPCache doesn't provide user cache  Use ext/apcu  apc_***() compatible API  No migration needed  Pretty stable
  56. 56. A word on OPCache for PHP 7  A binary format allowing OPCache to store onto the FileSystem and not only Shared Memory  This has been asked  Getting closer to compiled languages (Java)  New optimizer tricks  New memory performance tricks  Kernel Huge page usage if available
  57. 57. Thank you for listening

×