Slide 1

Slide 1 text

Scaling PHP in the real world Dustin Whittle - @dustinwhittle

Slide 2

Slide 2 text

PHP IS USED BY THE LIKES OF FACEBOOK, YAHOO, ZYNGA, TUMBLR, ETSY, AND WIKIPEDIA. HOW DO THE LARGEST INTERNET COMPANIES SCALE PHP TO MEET THEIR DEMAND? ! JOIN THIS SESSION AND FIND OUT HOW TO USE THE LATEST TOOLS IN PHP FOR DEVELOPING HIGH PERFORMANCE APPLICATIONS. WE’LL TAKE A LOOK AT COMMON TECHNIQUES FOR SCALING PHP APPLICATIONS AND BEST PRACTICES FOR PROFILING AND OPTIMIZING PERFORMANCE. AFTER THIS SESSION, YOU’LL LEAVE PREPARED TO TACKLE YOUR NEXT ENTERPRISE PHP PROJECT.

Slide 3

Slide 3 text

AGENDA • Why performance matters? • The problems with PHP • Best practice designs • Distributed data caches with Redis and Memcached • Doing work in the background with queues • Http caching and a reverse proxy with Varnish • Using the right tool for the job • Tools of the trade • Xdebug + WebGrind • XHProf + XHProf GUI • AppDynamics • Google PageSpeed • Architecture not applications

Slide 4

Slide 4 text

DUSTIN WHITTLE • dustinwhittle.com • @dustinwhittle • Technologist, Pilot, Skier, Diver, Sailor, Golfer

Slide 5

Slide 5 text

WHAT I HAVE WORKED ON • Developer Evangelist @ • Consultant & Trainer @ • Developer Evangelist @

Slide 6

Slide 6 text

DID YOU KNOW FACEBOOK, YAHOO, ZYNGA, TUMBLR, ETSY, AND WIKIPEDIA WERE ALL STARTED ON PHP?

Slide 7

Slide 7 text

WHY DOES PERFORMANCE MATTER?

Slide 8

Slide 8 text

WHEN MOZILLA SHAVED 2.2 SECONDS OFF THEIR LANDING PAGE, FIREFOX DOWNLOADS INCREASED 15.4%

Slide 9

Slide 9 text

MAKING BARACK OBAMA’S WEBSITE 60% FASTER INCREASED DONATION CONVERSIONS BY 14%

Slide 10

Slide 10 text

AMAZON AND WALMART INCREASED REVENUE 1% FOR EVERY 100MS OF IMPROVEMENT

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

PERFORMANCE DIRECTLY IMPACTS THE BOTTOM LINE

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

PHP IS SLOWER THAN JAVA, C++, ERLANG, SCALA, AND GO!

Slide 15

Slide 15 text

HTTP://PHPSADNESS.COM/

Slide 16

Slide 16 text

...AND PHP HAS SOME SERIOUS DESIGN ISSUES AND INCONSISTENCIES!

Slide 17

Slide 17 text

...BUT THERE ARE WAYS TO SCALE TO HANDLE HIGH TRAFFIC APPLICATIONS

Slide 18

Slide 18 text

PHP IS NOT YOUR PROBLEM!

Slide 19

Slide 19 text

WHAT VERSION OF PHP DO YOU RUN?

Slide 20

Slide 20 text

UPGRADE YOUR PHP ENVIRONMENT TO 2014!

Slide 21

Slide 21 text

NGINX + PHP-FPM

Slide 22

Slide 22 text

USE AN OPCODE CACHE!

Slide 23

Slide 23 text

PHP 5.5 HAS ZEND OPCACHE

Slide 24

Slide 24 text

APC

Slide 25

Slide 25 text

USE AUTOLOADING AND PSR-0

Slide 26

Slide 26 text

SYMFONY2 CLASSLOADER COMPONENT WITH APC CACHING

Slide 27

Slide 27 text

SCALING BEYOND A SINGLE SERVER IN PHP

Slide 28

Slide 28 text

OPTIMIZE YOUR SESSIONS!

Slide 29

Slide 29 text

THE DEFAULT IN PHP IS TO PERSIST SESSIONS TO DISK

Slide 30

Slide 30 text

IT IS BETTER TO STORE SESSIONS IN A DATABASE

Slide 31

Slide 31 text

EVEN BETTER IS TO STORE IN A DATABASE WITH A SHARED CACHE IN FRONT

Slide 32

Slide 32 text

PECL INSTALL MEMCACHED

Slide 33

Slide 33 text

session.save_handler = memcached session.save_path = "10.0.0.10:11211,10.0.0.11:11211,10.0.0.12:11211" memcached.sess_prefix = “session.” memcached.sess_consistent_hash = On memcached.sess_remove_failed = 1 memcached.sess_number_of_replicas = 2 memcached.sess_binary = On memcached.sess_randomize_replica_read = On memcached.sess_locking = On memcached.sess_connect_timeout = 200 memcached.serializer = “igbinary”

Slide 34

Slide 34 text

THE BEST SOLUTION IS TO LIMIT SESSION SIZE AND STORE ALL DATA IN A SIGNED OR ENCRYPTED COOKIE

Slide 35

Slide 35 text

LEVERAGE AN IN-MEMORY DATA CACHE

Slide 36

Slide 36 text

MEMCACHED.ORG

Slide 37

Slide 37 text

REDIS.IO

Slide 38

Slide 38 text

• Any data that is expensive to generate/query and long lived should be cached • Web Service Responses • HTTP Responses • Database Result Sets • Configuration Data

Slide 39

Slide 39 text

GUZZLE HTTP CLIENT HAS BUILT-IN SUPPORT FOR CACHING WEB SERVICE REQUESTS

Slide 40

Slide 40 text

$memcache = new Memcache(); $memcache->connect('localhost', 11211); ! $memcacheDriver = new Doctrine\Common\Cache\MemcacheCache(); $memcacheDriver->setMemcache($memcache); ! $client = new Guzzle\HttpClient(‘http://www.test.com/’); ! $cachePlugin = new Guzzle\Plugin\Cache\CachePlugin(array( ‘storage’ => new Guzzle\Plugin\Cache\DefaultCacheStorage( new Guzzle\Plugin\Cache\DoctrineCacheAdapter($memcacheDriver) ) )); $client->addSubscriber($cachePlugin); ! $response = $client->get(‘http://www.wikipedia.org/’)->send(); ! $response = $client->get(‘http://www.wikipedia.org/’)->send();

Slide 41

Slide 41 text

DOCTRINE ORM FOR PHP HAS BUILT-IN CACHING SUPPORT FOR MEMCACHED AND REDIS

Slide 42

Slide 42 text

$memcache = new Memcache(); $memcache->connect('localhost', 11211); ! $memcacheDriver = new Doctrine\Common\Cache\MemcacheCache(); $memcacheDriver->setMemcache($memcache); ! $config = new Doctrine\ORM\Configuration(); $config->setQueryCacheImpl($memcacheDriver); $config->setMetadataCacheImpl($memcacheDriver); $config->setResultCacheImpl($memcacheDriver); ! $entityManager = Doctrine\ORM\EntityManager::create(array(‘driver’ => ‘pdo_sqlite’, ‘path’ => __DIR__ . ‘/db.sqlite’), $config); ! $query = $em->createQuery(‘select u from EntitiesUser u’); $query->useResultCache(true, 60); ! $users = $query->getResult();

Slide 43

Slide 43 text

DO BLOCKING WORK IN BACKGROUND TASKS VIA QUEUES

Slide 44

Slide 44 text

• Resque • Gearman • RabbitMQ • Kafka • Beanstalkd • ZeroMQ • ActiveMQ

Slide 45

Slide 45 text

RESQUE

Slide 46

Slide 46 text

• Any process that is slow and not important for the http response should be queued • Sending notifications + posting to social accounts • Analytics + Instrumentation • Updating profiles and discovering friends from social accounts • Consuming web services like Twitter Streaming API

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

LEVERAGE HTTP CACHING

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

EXPIRES OR INVALIDATION

Slide 55

Slide 55 text

EXPIRATION

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

VALIDATION

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

EXPIRATION AND INVALIDATION

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

SYMFONY2 HTTPFOUNDATION COMPONENT WITH HTTP CACHING

Slide 66

Slide 66 text

use Symfony\Component\HttpFoundation\Response; ! $response = new Response(‘Hello World!’, 200, array(‘content-type’ => ‘text/html’)); ! $response->setCache(array( ‘etag’ => ‘a_unique_id_for_this_resource’, ‘last_modified’ => new DateTime(), ‘max_age’ => 600, ‘s_maxage’ => 600, ‘private’ => false, ‘public’ => true, ));

Slide 67

Slide 67 text

use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; ! $request = Request::createFromGlobals(); ! $response = new Response(‘Hello World!’, 200, array(‘content-type’ => ‘text/html’)); ! if ($response->isNotModified($request)) { $response->send(); }

Slide 68

Slide 68 text

• Varnish • Squid • Nginx Proxy Cache • Apache Proxy Cache

Slide 69

Slide 69 text

USE VARNISH AS A REVERSE PROXY CACHE TO ALLEVIATE LOAD ON YOUR APP SERVERS

Slide 70

Slide 70 text

OPTIMIZE YOUR FRAMEWORK!

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

• Stay up-to-date with the latest stable version of your favorite framework • Disable features you are not using (I18N, Security, etc) • Always use a data cache like Memcached/Redis • Enable caching features for views and database result sets • Always use a HTTP cache like Varnish

Slide 73

Slide 73 text

LEARN TO HOW TO PROFILE CODE FOR PHP PERFORMANCE

Slide 74

Slide 74 text

XDEBUG + WEBGRIND

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

XHPROF + XHPROF GUI

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

PHP AS GLUE

Slide 84

Slide 84 text

BACKEND = JAVA/SCALA/ ERLANG/GO/NODE ! FRONTEND = PHP OR JAVASCRIPT

Slide 85

Slide 85 text

YAHOO! & YPHP Move slow code to PHP extensions

Slide 86

Slide 86 text

FACEBOOK & HHVM A drop-in replacement for PHP (mostly)

Slide 87

Slide 87 text

No content

Slide 88

Slide 88 text

No content

Slide 89

Slide 89 text

No content

Slide 90

Slide 90 text

• Upgrade to PHP 5.5 with Zend OpCache using PHP-PFM + Nginx • Stay up to date with your framework + dependencies (using Composer) • Optimize your session store to use signed cookies or database with caching • Cache your database and web service access with Memcache or Redis • Do blocking work in the background with queues and tasks using Resque • Use HTTP caching and a reverse proxy cache like Varnish • Profile code with Xdebug + Webgrind and monitor production performance

Slide 91

Slide 91 text

DON’T FORGET TO OPTIMIZE THE CLIENT SIDE

Slide 92

Slide 92 text

IN MODERN WEB APPLICATIONS MOST OF THE LATENCY COMES FROM THE CLIENT SIDE

Slide 93

Slide 93 text

USE ASSETIC TO OPTIMIZE CLIENT-SIDE ASSETS

Slide 94

Slide 94 text

GOOGLE PAGESPEED

Slide 95

Slide 95 text

GOOGLE PAGESPEED INSIGHTS

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

GOOGLE PAGESPEED API

Slide 99

Slide 99 text

CURL "HTTPS://WWW.GOOGLEAPIS.COM/ PAGESPEEDONLINE/V1/RUNPAGESPEED? URL=HTTP://DUSTINWHITTLE.COM/ &KEY=XXX"

Slide 100

Slide 100 text

SCALABILITY IS ABOUT THE ENTIRE ARCHITECTURE, NOT SOME MINOR CODE OPTIMIZATIONS.

Slide 101

Slide 101 text

QUESTIONS?

Slide 102

Slide 102 text

FIND THESE SLIDES ON SPEAKERDECK: ! SPEAKERDECK.COM/DUSTINWHITTLE

Slide 103

Slide 103 text

No content