Performance all teh things

1,048 views

Published on

Slidedeck from Drupal Dev Days Dublin 2013

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,048
On SlideShare
0
From Embeds
0
Number of Embeds
18
Actions
Shares
0
Downloads
5
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Performance all teh things

  1. 1. @manarth Marcus Deglos Performance all teh things!
  2. 2. BREAKING NEWS Drupal is Slow!
  3. 3. JUST HOW SLOW ARE WE TALKING, EXACTLY?
  4. 4. BENCHMARKING A single request and response
  5. 5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
 "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" version="XHTML+RDFa 1.0" dir="ltr"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:dc="http://purl.org/dc/terms/"
 xmlns:foaf="http://xmlns.com/foaf/0.1/"
 xmlns:og="http://ogp.me/ns#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
 xmlns:sioc="http://rdfs.org/sioc/ns#"
 xmlns:sioct="http://rdfs.org/sioc/types#"
 xmlns:skos="http://www.w3.org/2004/02/skos/core#"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema#">

<head profile="http://www.w3.org/1999/xhtml/vocab">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="http://testbed.local/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<meta name="Generator" content="Drupal 7 (http://drupal.org)" />
 <title>Welcome to Site- Install | Site-Install</title> Compare: - Plain old HTML - Plain old HTML, with PHP overhead - Drupal
  6. 6. What HTML? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
 "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" version="XHTML+RDFa 1.0" dir="ltr"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:dc="http://purl.org/dc/terms/"
 xmlns:foaf="http://xmlns.com/foaf/0.1/"
 xmlns:og="http://ogp.me/ns#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
 xmlns:sioc="http://rdfs.org/sioc/ns#"
 xmlns:sioct="http://rdfs.org/sioc/types#"
 xmlns:skos="http://www.w3.org/2004/02/skos/core#"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema#">

<head profile="http://www.w3.org/1999/xhtml/vocab">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="http://testbed.local/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<meta name="Generator" content="Drupal 7 (http://drupal.org)" />
 <title>Welcome to Site-Install | Site-Install</title> Drupal 7’s homepage.
  7. 7. ApacheBench ab -n 1000 -c 10 $url
  8. 8. ApacheBench ab -n 1000 -c 10 $url 1000 requests 10 concurrent requests
  9. 9. How fast? HTML 1776 PHP 1437 Drupal 32 Requests per second (mean, averaged over 3 runs of 1000 requests)
  10. 10. How fast? HTML 1776 PHP 1437 Drupal 32 Requests per second (mean, averaged over 3 runs of 1000 requests)
  11. 11. HOW DO WE MAKE IT FASTER?
  12. 12. How do we make it faster? APC Memcache Varnish Drupal page cache Drupal block cache Apache tuning Custom- compiled PHP MySQL tuning Front-end optimisation ESI
  13. 13. How do we make it faster? APC Memcache Varnish Drupal page cache Drupal block cache Apache tuning Custom- compiled PHP MySQL tuning Front-end optimisation ESI
  14. 14. SIMPLE QUICK WINS APC, memcache, and Drupal caches
  15. 15. A Perfect Cure?
  16. 16. JUST WHAT IS THIS APC THING ANYWAY? APC: an opcode cache. Welcome to the world of PHP internals
  17. 17. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute
  18. 18. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute
  19. 19. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute <?php function display_data(array $data) { $buf = ''; foreach ($data as $k=>$v) { $buf .= sprintf("%s: %sn", $k, $v); } return $buf; }
  20. 20. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute
  21. 21. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute 1 OPEN_TAG <?php 2 WHITESPACE 3 FUNCTION function 3 WHITESPACE 3 STRING display_data 3 OPEN BRACKET ( 3 ARRAY array 3 WHITESPACE 3 VARIABLE $data 3 CLOSE_BRACKET ) 3 WHITESPACE 4 OPEN_CURLY { 4 WHITESPACE … …………………
  22. 22. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute
  23. 23. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute Tokens are compiled into op-codes Each op-code is represented by an integer. For example: OpcodeOpcode number CONCAT 8 DECLARE_CONST 143 UNSET_VAR 74
  24. 24. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute
  25. 25. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute zend_compile_file zend_execute
  26. 26. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute APC replaces this zend_execute
  27. 27. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute zend_execute The compiled opcodes for each file are cached in memory. No need to parse again.
  28. 28. Simplified workflow include “foo.php” Read contents of “foo.php” Tokenize Convert tokens to opcodes execute APC Summary You do not need to change your code APC cache is not shared between PHP-FPM workers Apache + mod php is better than PHP-FPM/CGI.
  29. 29. Installing APC $ sudo apt-get install php-apc Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: php-apc 0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/79.2 kB of archives. After this operation, 233 kB of additional disk space will be used. Selecting previously unselected package php-apc. (Reading database ... 68234 files and directories currently installed.) Unpacking php-apc (from .../php-apc_3.1.7-1_i386.deb) ... Processing triggers for libapache2-mod-php5 ... * Reloading web server config apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up php-apc (3.1.7-1) ... $ sudo apache2ctl restart
  30. 30. Installing APC $ sudo apt-get install php-apc Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: php-apc 0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/79.2 kB of archives. After this operation, 233 kB of additional disk space will be used. Selecting previously unselected package php-apc. (Reading database ... 68234 files and directories currently installed.) Unpacking php-apc (from .../php-apc_3.1.7-1_i386.deb) ... Processing triggers for libapache2-mod-php5 ... * Reloading web server config apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up php-apc (3.1.7-1) ... $ sudo apache2ctl restart Use `sudo` if you need more privileges than your user account has.
  31. 31. Installing APC $ sudo apt-get install php-apc Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: php-apc 0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/79.2 kB of archives. After this operation, 233 kB of additional disk space will be used. Selecting previously unselected package php-apc. (Reading database ... 68234 files and directories currently installed.) Unpacking php-apc (from .../php-apc_3.1.7-1_i386.deb) ... Processing triggers for libapache2-mod-php5 ... * Reloading web server config apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up php-apc (3.1.7-1) ... $ sudo apache2ctl restart Package manager command may vary according to O/S. Redhat/CentOS usually uses `yum install` instead.
  32. 32. Installing APC $ sudo apt-get install php-apc Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: php-apc 0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/79.2 kB of archives. After this operation, 233 kB of additional disk space will be used. Selecting previously unselected package php-apc. (Reading database ... 68234 files and directories currently installed.) Unpacking php-apc (from .../php-apc_3.1.7-1_i386.deb) ... Processing triggers for libapache2-mod-php5 ... * Reloading web server config apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up php-apc (3.1.7-1) ... $ sudo apache2ctl restart The name of the package varies according to distro, for example `php-pecl-apc` in some variations.
  33. 33. Installing APC $ sudo apt-get install php-apc Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: php-apc 0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/79.2 kB of archives. After this operation, 233 kB of additional disk space will be used. Selecting previously unselected package php-apc. (Reading database ... 68234 files and directories currently installed.) Unpacking php-apc (from .../php-apc_3.1.7-1_i386.deb) ... Processing triggers for libapache2-mod-php5 ... * Reloading web server config apache2 apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName [ OK ] Setting up php-apc (3.1.7-1) ... $ sudo apache2ctl restart Restart Apache for the change to take effect.
  34. 34. Verifying APC is running $ php -i |grep –iapc Additional .ini files parsed => /etc/php5/cli/conf.d/apc.ini, apc APC Support => disabled APC Debugging => Disabled apc.cache_by_default => On => On apc.canonicalize => On => On apc.coredump_unmap => Off => Off apc.enable_cli => Off => Off apc.enabled => On => On apc.file_md5 => Off => Off apc.file_update_protection => 2 => 2 apc.filters => no value => no value apc.gc_ttl => 3600 => 3600
  35. 35. Verifying APC is running $ php -i |grep –iapc Additional .ini files parsed => /etc/php5/cli/conf.d/apc.ini, apc APC Support => disabled APC Debugging => Disabled apc.cache_by_default => On => On apc.canonicalize => On => On apc.coredump_unmap => Off => Off apc.enable_cli => Off => Off apc.enabled => On => On apc.file_md5 => Off => Off apc.file_update_protection => 2 => 2 apc.filters => no value => no value apc.gc_ttl => 3600 => 3600 Use `php –i` to show the PHP environment configuration
  36. 36. Verifying APC is running $ php -i |grep –iapc Additional .ini files parsed => /etc/php5/cli/conf.d/apc.ini, apc APC Support => disabled APC Debugging => Disabled apc.cache_by_default => On => On apc.canonicalize => On => On apc.coredump_unmap => Off => Off apc.enable_cli => Off => Off apc.enabled => On => On apc.file_md5 => Off => Off apc.file_update_protection => 2 => 2 apc.filters => no value => no value apc.gc_ttl => 3600 => 3600 Use `grep` to filter for config related just to APC. The `-i` flag is to ignore case.
  37. 37. Verifying APC is running $ php -i |grep –iapc Additional .ini files parsed => /etc/php5/cli/conf.d/apc.ini, apc APC Support => disabled APC Debugging => Disabled apc.cache_by_default => On => On apc.canonicalize => On => On apc.coredump_unmap => Off => Off apc.enable_cli => Off => Off apc.enabled => On => On apc.file_md5 => Off => Off apc.file_update_protection => 2 => 2 apc.filters => no value => no value apc.gc_ttl => 3600 => 3600 Hooray!
  38. 38. Verifying via the browser Link to PHP configuration Admin » Reports » Status
  39. 39. Verifying via the browser
  40. 40. Benchmarking time!
  41. 41. How fast? Requests per second (mean, averaged over 3 runs of 1000 requests) No APC 3.75 APC 3.44
  42. 42. Wait, WHAT?!
  43. 43. How fast? Requests per second (mean, averaged over 3 runs of 1000 requests) No APC 3.75 APC 3.44 I cheated. This is what happens when you don’t assign enough memory to APC.
  44. 44. How fast? Requests per second (mean, averaged over 3 runs of 1000 requests) No APC 3.75 APC 3.44 APC 12.49
  45. 45. Memcache What does it do?
  46. 46. cache_get if ($cache = cache_get('image_styles', 'cache')) { $styles = $cache->data; } else { // Do a load of work // And look up all sorts of things in the SLOW db. }
  47. 47. cache_get if ($cache = cache_get('image_styles', 'cache')) { $styles = $cache->data; } else { // Do a load of work // And look up all sorts of things in the SLOW db. } cache_get is pluggable. It’s a key-value store. By default it uses the DB.
  48. 48. cache_get in the DB. cache_get('image_styles', 'cache’); SELECT * from cache WHERE cid='image_styles’;
  49. 49. A quick summary Memcache moves load from the DB to memcache. Memcache stores data in memory (unlike DB which stores it on disk). Memory is faster. Memcache is non-persistent. Don’t store data you’re not prepared to lose.
  50. 50. Installing Memcache $ sudo apt-get installmemcachedphp5-memcache Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libmemcached6 Use 'apt-get autoremove' to remove them. Suggested packages: libcache-memcached-perllibmemcached The following NEW packages will be installed: memcached php5-memcache 0 upgraded, 2 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/121 kB of archives. After this operation, 375 kB of additional disk space will be used. Selecting previously unselected package memcached. (Reading database ... 68214 files and directories currently installed.) …… Setting up memcached (1.4.13-0ubuntu2) ... Starting memcached: memcached. Setting up php5-memcache (3.0.6-1) ... $ sudo /etc/init.d/memcached start Starting memcached: memcached.
  51. 51. Installing Memcache $ sudo apt-get installmemcachedphp5-memcache Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libmemcached6 Use 'apt-get autoremove' to remove them. Suggested packages: libcache-memcached-perllibmemcached The following NEW packages will be installed: memcached php5-memcache 0 upgraded, 2 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/121 kB of archives. After this operation, 375 kB of additional disk space will be used. Selecting previously unselected package memcached. (Reading database ... 68214 files and directories currently installed.) …… Setting up memcached (1.4.13-0ubuntu2) ... Starting memcached: memcached. Setting up php5-memcache (3.0.6-1) ... $ sudo /etc/init.d/memcached start Starting memcached: memcached. memcachedis the memcache server. It’s a standalone program, completely separate from PHP.
  52. 52. Installing Memcache $ sudo apt-get installmemcachedphp5-memcache Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libmemcached6 Use 'apt-get autoremove' to remove them. Suggested packages: libcache-memcached-perllibmemcached The following NEW packages will be installed: memcached php5-memcache 0 upgraded, 2 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/121 kB of archives. After this operation, 375 kB of additional disk space will be used. Selecting previously unselected package memcached. (Reading database ... 68214 files and directories currently installed.) …… Setting up memcached (1.4.13-0ubuntu2) ... Starting memcached: memcached. Setting up php5-memcache (3.0.6-1) ... $ sudo /etc/init.d/memcached start Starting memcached: memcached. php5-memcache is the PHP extension that provides functions for PHP to exchange data with a memcache server.
  53. 53. Installing Memcache $ sudo apt-get installmemcachedphp5-memcache Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libmemcached6 Use 'apt-get autoremove' to remove them. Suggested packages: libcache-memcached-perllibmemcached The following NEW packages will be installed: memcached php5-memcache 0 upgraded, 2 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/121 kB of archives. After this operation, 375 kB of additional disk space will be used. Selecting previously unselected package memcached. (Reading database ... 68214 files and directories currently installed.) …… Setting up memcached (1.4.13-0ubuntu2) ... Starting memcached: memcached. Setting up php5-memcache (3.0.6-1) ... $ sudo /etc/init.d/memcached start Starting memcached: memcached. There’s another PHP extension called php5- memcached, which does the same thing. PHP also has duplicate modules!
  54. 54. Installing Memcache $ sudo apt-get installmemcachedphp5-memcache Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libmemcached6 Use 'apt-get autoremove' to remove them. Suggested packages: libcache-memcached-perllibmemcached The following NEW packages will be installed: memcached php5-memcache 0 upgraded, 2 newly installed, 0 to remove and 8 not upgraded. Need to get 0 B/121 kB of archives. After this operation, 375 kB of additional disk space will be used. Selecting previously unselected package memcached. (Reading database ... 68214 files and directories currently installed.) …… Setting up memcached (1.4.13-0ubuntu2) ... Starting memcached: memcached. Setting up php5-memcache (3.0.6-1) ... $ sudo /etc/init.d/memcached start Starting memcached: memcached. Start the memcache server
  55. 55. Drupal config for Memcache Download the memcache module. Add the configuration to settings.php.
  56. 56. settings.php changes /** * Memcache configuration. */ define('MEMCACHE_PATH', 'sites/all/modules/contrib/memcache/memcache.inc'); // Include the base cache class that memcache extends. include_once('./includes/cache.inc'); // Include the memcache files. include_once(MEMCACHE_PATH); // Optionally configure a prefix; most sites won't need this. # $conf['memcache_key_prefix'] = 'foo'; // Declare memcache as a potential backend. $conf['cache_backends'][] = MEMCACHE_PATH; // Set the default cache to use memcache. $conf['cache_default_class'] = 'MemCacheDrupal'; // Form-cache must use non-volatile storage. $conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
  57. 57. How fast? Requests per second (mean, averaged over 3 runs of 1000 requests) APC 12.49 Memcache 29.06
  58. 58. How fast? Page cache 55 + APC 190 + APC + memcache 193 Requests per second (mean, averaged over 3 runs of 1000 requests) APC 12.49
  59. 59. Varnish…live demo! (uh oh…)
  60. 60. A QUICK SUMMARY
  61. 61. Speeding up the snail • APC and memcache are quick wins. • Turn on page-caching and block-caching • Use Varnish for static assets • Use Varnish + ESI to cache authenticated users
  62. 62. Thanks for coming!  Blog: http://deglos.com  Email: marcus@techito.co.uk  Slides: http://slideshare.net/manarth  Twitter: @manarth Questions?
  63. 63.  Build websites  Develop modules  Offer technical consultancy http://techito.co.uk/

×