Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHP Performance I: Everything You Need to Know about OpCode Caches

Davey Shafik
September 30, 2013

PHP Performance I: Everything You Need to Know about OpCode Caches

Davey Shafik

September 30, 2013
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. PHP Performance I
    Everything you need to know about
    OpCode caches

    View full-size slide

  2. •Community Engineer at Engine
    Yard
    •Author of Zend PHP 5
    Certification Study Guide,
    Sitepoints PHP Anthology: 101
    Essential Tips, Tricks & Hacks
    & PHP Master: Write Cutting
    Edge Code
    •A contributor to Zend
    Framework 1 & 2, phpdoc, and
    PHP internals
    •@dshafik
    Davey Shafik

    View full-size slide

  3. What are OpCode Caches?

    View full-size slide

  4. What are OpCode Caches?
    • Performance enhancing extensions for PHP
    • Inject themselves into the execution life-cycle of PHP
    and cache as much of it as possible
    • Common to see a 300% speed increase with default
    settings!
    4

    View full-size slide

  5. When Should I Use an
    OpCache?

    View full-size slide

  6. Always.
    No, really.

    View full-size slide

  7. Side Effects
    (I knew it couldn’t be that easy!)

    View full-size slide

  8. Cache Stampede

    View full-size slide

  9. Side Effects
    The primary side effect of using a cache is known as a
    cache stampede.
    This is where your cache expires while under heavy
    load.
    Caused by:
    • Restarting Server
    • Cache invalidation because of data edits
    • Newly provisioned servers being added to a cluster to help
    scale under load
    • Corruption (hardware issues)

    View full-size slide

  10. Which OpCode Cache

    View full-size slide

  11. Which OpCode Cache
    • There have been many caches, however till PHP 5.5
    the dominant choice was the Alternative PHP Cache
    (APC)
    • With PHP 5.5, Zend open sourced it’s proprietary
    Zend OpCache and contributed it to the PHP project
    • Zend OpCache is now enabled by default with PHP
    5.5+ unless disabled by --disable-all.
    • Zend OpCache is between 6-100% faster than APC
    11

    View full-size slide

  12. Which OpCode Cache
    • PHP 5.3 or 5.4, choose between Zend OpCache and
    Alternative PHP Cache (APC)
    • PHP 5.5+, we recommend Zend OpCache
    • Zend OpCache can be used with PHP 5.2+
    12

    View full-size slide

  13. Which OpCode Cache
    • A second extension can be installed alongside Zend
    OpCache to give backwards compatibility with APC’s
    User Cache: APCu
    • APCu is APC with the OpCode Caching removed
    • 100% Backwards Compatible
    13

    View full-size slide

  14. Installation

    View full-size slide

  15. Zend OpCache

    View full-size slide

  16. Installing Zend OpCache
    $ pecl install zendopcache-beta
    Add the following to your php.ini:
    [zendopcache]
    zend_extension=/full/path/to/opcache.so ; May be added by pecl
    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
    Restart PHP (php-fpm/apache)

    View full-size slide

  17. Installing APC
    $ pecl install apc-beta
    Add the following to your php.ini:
    [apc]
    extension=apc.so ; May be added by pecl
    apc.enabled=1
    Restart PHP (php-fpm/apache)

    View full-size slide

  18. APCu
    (Optional)
    For APC User Cache Compatibility

    View full-size slide

  19. Installing APCu
    $ pecl install apcu-beta
    Add the following to your php.ini:
    [apcu]
    extension=apcu.so ; May be added by pecl
    apc.serializer=php ; See bug report for more info: http://ey.io/1aJhcOY
    Restart PHP (php-fpm/apache)

    View full-size slide

  20. Engine Yard
    PHP Performance Tools

    View full-size slide

  21. Engine Yard PHP Performance Tools
    • A suite of tools to aid with improving PHP
    performance
    • Open Source, Apache 2.0 License
    • On Github: http://github.com/engineyard/ey-php-
    performance-tools
    • Composer Compatible Package
    22

    View full-size slide

  22. Installation
    Add composer.json configuration:
    "repositories": [
    {
    "type": "vcs",
    "url": "http://github.com/engineyard/ey-php-
    performance-tools"
    }
    ],
    "require": {
    "php": ">=5.3.3",
    "engineyard/php-performance-tools": "dev-master"
    }
    Run composer update:
    $ composer.phar update engineyard/php-performance-tools

    View full-size slide

  23. Solving The Cache Stampede

    View full-size slide

  24. Priming The Cache

    View full-size slide

  25. Zend OpCache

    View full-size slide

  26. cache-primer

    View full-size slide

  27. cache-primer
    Create a config.php:
    return [
    /* URLs to cache */
    'urls' => [
    'http://ephernote.com/',
    'http://ephernote.com/user/login',
    'http://ephernote.com/user/register',
    'http://ephernote.com/privary', // Note: this is a
    typo
    ],
    /* How many concurrent HTTP requests to make (requires
    the pecl_http extension) */
    'threads' => 3
    ];

    View full-size slide

  28. cache-primer
    Run the primer:
    $ /path/composer/vendor/bin/cache-primer
    === Cache Primer ===
    Attempting to cache 4 URLs:
    Running in parallel with 3 concurrent requests
    ...!
    Cached 3 URLs in 0.6162059307098 seconds
    Encountered 1 errors

    View full-size slide

  29. cache-primer
    === Cache Primer ===
    Attempting to cache 104 URLs:
    Running in parallel with 10 concurrent requests
    ..........................................................
    ..................!...........................
    Cached 103 URLs in 4.6162059307098 seconds
    Encountered 1 errors

    View full-size slide

  30. Priming the Cache (APC)
    • Has built-in tools for priming the cache
    • Still requires a single HTTP request
    • Can cache more than just easily web accessible code
    • Any valid PHP can be cached, including partial view
    templates, global code, etc.
    • Use: engineyard/php-performance-tools/apc-primer
    33

    View full-size slide

  31. apc-primer
    • Provides basic HTTP security
    • We recommend not relying on it, instead integrate it behind
    other authentication instead (e.g. embed it into your admin
    control panel)
    • Uses apc_compile_file() to add code to the cache
    • Requires a wrapper to expose via HTTP
    • Caches all .php and .phtml files not inside a tests
    directory
    34

    View full-size slide

  32. apc-primer
    Create a config.php:
    if (!defined('DS')) {
    define('DS', DIRECTORY_SEPARATOR);
    }
    return [
    /* HTTP Basic Authentication: NOT RECOMMENDED */
    'auth' => [
    'enabled' => true,
    'username' => 'admin',
    'password' => 'changeme',
    ],
    /* Paths to cache (recursively) */
    'paths' => [
    __DIR__ .DS. '..' .DS. '..' .DS. '..' .DS. 'config',
    __DIR__ .DS. '..' .DS. '..' .DS. '..' .DS. 'module',
    __DIR__ .DS. '..' .DS. '..' .DS. '..' .DS. 'vendor',
    __DIR__ .DS. '..' .DS. '..' .DS. '..' .DS. 'public',
    ]
    ];

    View full-size slide

  33. apc-primer
    Place a simple wrapper in your web-root, e.g.
    /public/admin/apc-cache-primer.php
    // public/admin/apc-cache-primer.php
    require '../../vendor/engineyard/php-performance-
    tools/apc-primer/apc-primer.php';
    Request the file via HTTP:
    Cached 4841 files in 2.1302671432495 seconds

    View full-size slide

  34. Under the Hood
    OR: Here be dragons!

    View full-size slide

  35. Execution Life-Cycle

    View full-size slide

  36. Execution Life-cycle: PHP vs Java
    39

    View full-size slide

  37. Execution Lifecycle with an OpCode Cache

    View full-size slide

  38. Tokens & OpCodes

    View full-size slide

  39. The Worst Hello World, Ever
    class Greeting {
    public function sayHello($to) {
    echo "Hello $to";
    }
    }
    $greeter = new Greeting();
    $greeter->sayHello("World");
    ?>

    View full-size slide

  40. Token Name Value
    T_OPEN_TAG T_CLASS class
    T_WHITESPACE
    T_STRING Greeting
    T_WHITESPACE
    {
    T_WHITESPACE
    T_PUBLIC public
    T_WHITESPACE
    T_FUNCTION function
    T_WHITESPACE
    T_STRING sayHello
    (
    T_VARIABLE $to
    )
    T_WHITESPACE
    {
    T_WHITESPACE
    T_ECHO echo
    T_WHITESPACE
    "
    T_ENCAPSED_AND_WHITESPACE Hello
    T_VARIABLE $to
    "
    ;
    Token Name Value
    T_WHITESPACE
    }
    T_WHITESPACE
    }
    T_WHITESPACE
    T_VARIABLE $greeter
    T_WHITESPACE
    =
    T_WHITESPACE
    T_NEW new
    T_WHITESPACE
    T_STRING Greeting
    (
    )
    ;
    T_WHITESPACE
    T_VARIABLE $greeter
    T_OBJECT_OPERATOR ->
    T_STRING sayHello
    (
    T_CONSTANT_ENCAPSED_STRING "World"
    )
    ;
    T_WHITESPACE
    T_CLOSE_TAG ?>
    Tokenizing

    View full-size slide

  41. Tokenizing
    • Note the difference between interpolated and non-
    interpolated strings.
    • They are both double quoted strings!
    • Interpolated: 4 Tokens
    • Non-interpolated: 1 Token
    • Start to see why this matters for performance: but
    don’t get caught up by micro-optimizations.
    45
    "
    T_ENCAPSED_AND_WHITESPACE Hello
    T_VARIABLE $to
    "
    T_CONSTANT_ENCAPSED_STRING "World"

    View full-size slide

  42. VLD
    Vulcan Logic Dumper

    View full-size slide

  43. VLD — Vulcan Logic Dumper
    • An extension to dump the compiled opcodes
    • Installed via PECL
    $ pecl install vld-beta
    Add the following to php.ini:
    extension=vld.so
    • Use via command line:
    $ php -dvld.active=1 -dvld.execute=0
    48

    View full-size slide

  44. VLD — Vulcan Logic Dumper
    • Outputs, in order:
    • global code (main script)
    • global functions
    • class functions
    49

    View full-size slide

  45. Understanding VLD Dumps
    Class Greeting:
    Function sayhello:
    filename: ./Greeting.php
    function name: sayHello
    Header
    compiled vars: !0 = $to
    number of ops: 8

    View full-size slide

  46. Understanding VLD Dumps (Cont.)
    • line: The line number in the source file
    • #: The opcode number
    • *: entry (left aligned) and exit points (right aligned), indicated by greater
    than symbols (>)
    • op: The opcode name
    • fetch: Details on global variable fetches (super globals, or the use of the
    global keyword)
    • ext: Extra data associated with the opcode, for example the opcode to
    which it should JMP
    • return: The location where return data from the operation is stored
    • operands: the operands used by the opcode (e.g. two variables to concat)
    51
    line # * op fetch ext return operands
    ----------------------------------------------------------------

    View full-size slide

  47. VLD — Variables
    • Four types of variables
    1. Exclamation point (!) are compiled variables (CVs) — these
    are pointers to userland variables
    2. Tilde (~) are temporary variables used for temporary
    storage (TMP_VARs) of in-process operations
    3. Dollar ($) are another type of temporary variables (VARs)
    which are tied to userland variables like CVs and therefore
    require things like refcounting.
    4. Colon (:) are temporary variables used for the storage of
    the result of lookups in the class hashtable
    52

    View full-size slide

  48. class Greeting -> sayHello
    Class Greeting:
    Function sayhello:
    compiled vars: !0 = $to
    line # * op fetch ext return operands
    ----------------------------------------------------------------
    3 0 > EXT_NOP
    1 RECV !0
    5 2 EXT_STMT
    3 ADD_STRING ~0 'Hello+'
    4 ADD_VAR ~0 ~0, !0
    5 ECHO ~0
    6 6 EXT_STMT
    7 > RETURN null
    class Greeting {
    public function sayHello($to) {
    echo "Hello $to";
    }
    }

    View full-size slide

  49. class Greeting -> sayHello
    • RECV: The function receives a value which is assigned
    to !0 (which represents $to)
    • ADD_STRING: Next we create a temporary variable
    identified by a ~, ~0 and assign the static string,
    'Hello+', where the + represents a space
    • ADD_VAR: After this, we concat the contents our
    variable, !0 to our temporary variable, ~0
    • ECHO: Then we echo that temporary variable
    • RETURN: Finally we return nothing as the function
    ends
    54

    View full-size slide

  50. Main Script
    compiled vars: !0 = $greeter
    line # * op fetch ext return operands
    --------------------------------------------------------------------
    2 0 > EXT_STMT
    1 NOP
    9 2 EXT_STMT
    3 FETCH_CLASS 4 :1 'Greeting'
    4 EXT_FCALL_BEGIN
    5 NEW $2 :1
    6 DO_FCALL_BY_NAME 0
    7 EXT_FCALL_END
    8 ASSIGN !0, $2
    10 9 EXT_STMT
    10 INIT_METHOD_CALL !0, 'sayHello'
    11 EXT_FCALL_BEGIN
    12 SEND_VAL 'World'
    13 DO_FCALL_BY_NAME 1
    14 EXT_FCALL_END
    12 15 EXT_STMT
    16 > RETURN 1
    $greeter = new Greeting();
    $greeter->sayHello("World");

    View full-size slide

  51. Main Script
    • FETCH_CLASS: First we lookup the class, Greeting; we store
    this reference in :1
    • NEW: Then we instantiate an instance of the class (:1) and
    assign it to a VAR, $2, and
    • DO_FCALL_BY_NAME: call the constructor
    • ASSIGN: Next we assign the resulting object (in VAR $2) to
    our CV (!0)
    • INIT_METHOD_CALL: We start calling the sayHello method,
    and
    • SEND_VAL: pass in 'World' to the method, and
    • DO_FCALL_BY_NAME: Actually execute the method
    • RETURN: The script ends successfully, with an implicit return
    of 1.
    56

    View full-size slide

  52. 57
    Resources
    • Zend OpCache Source Code: http://ey.io/17Qt6W9
    • Zend OpCache PECL Package: http://ey.io/18h2Inp
    • APC Source Code: http://ey.io/18gZ9iW
    • APC PECL Package: http://ey.io/15JuQkp
    • Understanding Opcodes (Sara Golemon): http://ey.io/19q32iD
    • More source analysis with VLD (Derick Rethans): http://ey.io/bx0q8N
    http://ey.io/opcaches

    View full-size slide

  53. http://ey.io/opcaches
    Feedback & Questions:
    Twitter: @dshafik
    Email: [email protected]

    View full-size slide