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

OSCON - Scaling PHP in the real world!

OSCON - Scaling PHP in the real world!

Scaling PHP in the real world! - Presented at OSCON 2014.

Dustin Whittle

July 23, 2014
Tweet

More Decks by Dustin Whittle

Other Decks in Technology

Transcript

  1. 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.
  2. 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
  3. WHAT I HAVE WORKED ON • Developer Evangelist @ •

    Consultant & Trainer @ • Developer Evangelist @
  4. APC

  5. 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”
  6. THE BEST SOLUTION IS TO LIMIT SESSION SIZE AND STORE

    ALL DATA IN A SIGNED OR ENCRYPTED COOKIE
  7. • Any data that is expensive to generate/query and long

    lived should be cached • Web Service Responses • HTTP Responses • Database Result Sets • Configuration Data
  8. $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();
  9. $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();
  10. • 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
  11. 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, ));
  12. 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(); }
  13. • 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
  14. • 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