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

Varnish your application - Make it fly!

Varnish your application - Make it fly!

Apply varnish to a pre-existing application to improve performance and scalability. Delivered at #phpnw11

Alistair Stead

October 08, 2011
Tweet

More Decks by Alistair Stead

Other Decks in Programming

Transcript

  1. VARNISH
    YOUR
    APPLICATION
    Make it fly!

    View Slide

  2. WHO AM I
    • Alistair Stead - @alistairstead
    • Technical Team Lead @ Ibuildings UK
    • Over 12 years commercial experience developing in PHP and
    other technologies.
    • http://joind.in/3591

    View Slide

  3. PERFORMANCE AND
    SCALABILITY
    Is a hot topic for clients and developers alike.

    View Slide

  4. PERFORMANCE
    Vs
    CONVERSION RATE
    These are directly linked!

    View Slide

  5. PERCEIVED PERFORMANCE
    Vs
    PHYSICAL PERFORMANCE
    Is there an easy route to performance?

    View Slide

  6. VARNISH
    http://www.varnish-cache.org/

    View Slide

  7. PRELIMINARY LOAD TESTS
    What can Varnish do for us?

    View Slide

  8. +4,000,000
    Requests per hour

    View Slide

  9. REVERSE PROXY?
    Yeah okay... tell me more!

    View Slide

  10. CACHING PROXY?
    It is...

    View Slide

  11. LOAD BALANCER?
    It can do that too!

    View Slide

  12. HTTP ACCELERATOR
    It may just be magic!

    View Slide

  13. WHERE TO APPLY VARNISH
    Apply thinly over your apache cluster
    Client
    Browser
    Varnish
    Port 80
    Backend
    Apache
    Port 8080
    Backend
    Apache
    Port 8080
    Client
    Browser
    Client
    Browser

    View Slide

  14. INSTALLATION
    Packages available for most platforms
    http://bit.ly/pPB7x5

    View Slide

  15. "WITH GREAT POWER COMES
    GREAT RESPONSIBILITY"

    View Slide

  16. HOW TO CONTROL CACHING
    Additional caching layers need to be coordinated

    View Slide

  17. RFC 2616 HTTP 1.1
    http://bit.ly/pLtSl0
    http://bit.ly/oORXf3

    View Slide

  18. HTTP 1.1
    $ curl -I magentocommerce.com

    View Slide

  19. HTTP/1.1 200 OK
    Server: nginx
    Date: Sun, 05 Jun 2011 17:40:56 GMT
    Content-Type: text/html; charset=UTF-8
    Connection: keep-alive
    X-Powered-By: PHP/5.2.17
    Set-Cookie:
    PHPSESSID=j1cdbj2617abbl8ccsbkd2mt44; path=/
    Expires: Mon, 26 Jul 1997 05:00:00 GMT
    Cache-Control: no-store, no-cache, must-
    revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Last-Modified: Sun, 05 Jun 2011 17:40:56 GMT
    $ curl -I magentocommerce.com

    View Slide

  20. HTTP 1.1 HEADERS
    Request modifiers / Response parameters

    View Slide

  21. CACHEING WITH HTTP 1.1
    Has two models Expiration & Validation

    View Slide

  22. EXPIRATION MODEL
    How long may I use this resource for?

    View Slide

  23. EXPIRATION HEADERS
    • Cache-Control
    • Expires

    View Slide

  24. VALIDATION MODEL
    Is this resource still okay to use?

    View Slide

  25. VALIDATION HEADERS
    • Last-Modified
    • If-Modified-Since
    • ETag
    • If-None-Match

    View Slide

  26. HTTP CACHE HEADERS
    Should only work with safe HTTP verbs GET & HEAD

    View Slide

  27. HTTP 1.1 REQUEST FLOW

    View Slide

  28. Client
    Application
    Client Cache
    GET / HTTP1.1
    Host: mystore.com
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    HTTP1.1 200 OK

    View Slide

  29. Client
    Application
    Client Cache
    GET / HTTP1.1
    Host: mystore.com
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control:
    max-age=20

    View Slide

  30. Client
    Application
    Client Cache
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control:
    max-age=20

    View Slide

  31. Client
    Application
    Client Cache
    GET / HTTP1.1
    Host: mystore.com
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Etag: abcde
    HTTP1.1 200 OK
    Etag: abcde
    HTTP1.1 200 OK
    Etag: abcde

    View Slide

  32. Client
    Application
    Client Cache
    GET / HTTP1.1
    Host: mystore.com GET / HTTP1.1
    Host: mystore.com
    If-None-Match: abcde
    HTTP1.1 304 Not
    Modified
    HTTP1.1 304 Not
    Modified
    HTTP1.1 200 OK
    Etag: abcde

    View Slide

  33. EXPIRATION ALLOWS YOU TO
    SCALE
    VALIDATION SAVES
    BANDWIDTH
    Fewer requests hitting your server and client speed is better too!

    View Slide

  34. OUR GOAL IS TO NEVER
    GENERATE THE SAME
    RESPONSE TWICE

    View Slide

  35. LEVERAGE HTTP CACHE IN
    MAGENTO
    With an event observer this is simple.

    View Slide

  36. class Disclosure_Varnish_Model_Observer extends Disclosure_Varnish_Model_Observer_Abstract
    {
    /**
    * Update the headers transmitted to allow greater varnish cache hits
    *
    * @param $observer
    */
    public function processPreDispatch(Varien_Event_Observer $observer)
    {
    if (!$this->isVarnishEnabled()) {
    return $this;
    }
    $routeTtls = $this->_config->getRouteTtls();
    $routeName = Mage::app()->getRequest()->getRequestedRouteName();
    if (isset($routeTtls[$routeName])) {
    $observer->getResponse()->setHeader('Cache-Control', $routeTtls[$routeName]
    ['cache_control'], false);
    }
    return $this;
    }
    }

    View Slide






  37. cms
    public, max-age=3600


    catalog
    public, must-revalidate, max-age=0

    private, max-age=0





    View Slide

  38. VARNISH RESPECTS CACHE
    CONTROL
    Dispatch the headers that fit your application

    View Slide

  39. Client
    Application
    Client Cache
    Reverse Proxy Cache
    GET / HTTP1.1
    Host: mystore.com
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control:
    max-age=20

    View Slide

  40. Client
    Application
    Client Cache
    Reverse Proxy Cache
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control:
    max-age=20

    View Slide

  41. Client
    Application
    Client Cache
    Reverse Proxy Cache
    GET / HTTP1.1
    Host: mystore.com
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20
    HTTP1.1 200 OK
    Cache-Control:
    max-age=20
    Client
    Client Cache
    GET / HTTP1.1
    Host: mystore.com
    HTTP1.1 200 OK
    Cache-Control: max-
    age=20

    View Slide

  42. Client
    Application
    Client Cache
    Reverse Proxy Cache
    Client
    Client Cache
    Gateway Cache
    Network Proxy Cache
    max-age
    s-maxage
    max-age
    s-maxage
    max-age
    s-maxage
    max-age
    max-age

    View Slide

  43. VARNISH IS CONFIGURED
    USING VCL
    Send the correct headers you should not need to do much.

    View Slide

  44. backend www1 {
    .host = "192.168.100.2";
    .port = "8080";
    }
    backend www2 {
    .host = "192.168.100.3";
    .port = "8080";
    }
    ........
    director backend_director random {
    .retries = 5;
    { .backend = www1; .weight = 1; }
    { .backend = www2; .weight = 1; }
    { .backend = www3; .weight = 1; }
    { .backend = www4; .weight = 1; }
    { .backend = www5; .weight = 1; }
    { .backend = www6; .weight = 1; }
    { .backend = www7; .weight = 1; }
    }

    View Slide

  45. sub vcl_deliver {
    # Set a cache header to allow us to inspect the response
    # headers during testing
    if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
    set resp.http.X-Cache-Hits = obj.hits;
    } else {
    set resp.http.X-Cache = "MISS";
    }
    }

    View Slide

  46. EDGE SIDE INCLUDES
    http://bit.ly/nITuFP

    View Slide

  47. sub vcl_recv {
    set req.http.Surrogate-Capability = "magento=ESI/1.0";
    return (lookup);
    }
    sub vcl_fetch {
    if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
    # unset beresp.http.Surrogate-Control;
    esi;
    }
    return (deliver);
    }

    View Slide

  48. max-age=3600
    max-age=86400

    View Slide

  49. max-age=3600
    max-age=86400

    View Slide

  50. ESI TAGS

    View Slide

  51. /**
    * Render ESI tags for the block if needed
    *
    * @param Varien_Event_Observer $observer
    */
    public function renderBlockEsiTag(Varien_Event_Observer $observer)
    {
    if (!$this->isEsiEnabled() || !$this->isVarnishEnabled()) {
    return $this;
    }
    $block = $observer->getEvent()->getBlock();
    $transport = $observer->getEvent()->getTransport();
    $tag = Mage::getModel('varnish/esi_tag_factory')-
    >create($block);
    if ($transport && $tag) {
    $transport->setHtml($tag->getHtml());
    }
    return $this;
    }

    View Slide

  52. /**
    * Render the html for the ESI tag
    *
    * @return string
    * @author Alistair Stead
    **/
    public function getHtml()
    {
    return sprintf(
    '',
    $this->getAttributeHash()
    );
    }

    View Slide

  53. class Disclosure_Varnish_EsiController extends Mage_Core_Controller_Front_Action
    {
    public function indexAction()
    {
    $attributes = unserialize(base64_decode($this->getRequest()-
    >getParam('attributes')));
    $context = Mage::getModel('varnish/esi_context');
    $context->setData($attributes);
    $processor = Mage::getModel('varnish/esi_processor', $context);
    // Initialize the layout
    $this->loadLayout();
    Mage::dispatchEvent('varnish_controller_esi_appendbody_before', array("response" =>
    $this->getResponse()));
    $this->getResponse()->appendBody($processor->render());
    Mage::dispatchEvent('varnish_controller_esi_appendbody_after', array("response" =>
    $this->getResponse()));
    }
    }

    View Slide

  54. FINAL PERFORMANCE RESULTS
    How much traffic did these modifications let us serve

    View Slide

  55. TRAFFIC SAMPLE
    • Product Details page: 58k views
    per hour
    • Homepage: 50k requests per hour
    • Main Search : 70k requests per
    hour
    • Refined Search (via facets): 20k
    requests per hour
    • Add to Basket: 11k requests per
    hour
    • Login: 11k requests per hour
    • Category Pages: 46k requests per
    hour
    • Checkout: 6k requests per hour

    View Slide

  56. Homepage
    Category Listings
    Product Detail
    Add to cart
    Login
    Search
    Purchase
    0 375000 750000 1125000 1500000
    Client Baseline Magento Baseline Magento Compiler
    Magento + Varnish
    FINAL PERFORMANCE RESULTS

    View Slide

  57. NON CACHEABLE
    TRANSACTIONS
    Add to cart
    Purchase
    0 7500 15000 22500 30000
    Client Baseline Magento Baseline Magento Compiler
    Magento + Varnish

    View Slide

  58. View Slide

  59. THE TARGET ~ 300K REQUEST
    We achieved almost 14 x that with little effort.

    View Slide

  60. IS VARNISH THE BEST
    SOLUTION?
    What do we need to consider?

    View Slide

  61. VARNISH LIMITATIONS
    • Prior to V3 ESI not supported with GZIP
    • Cookies need to be managed carefully
    • Still need SSL endpoint
    • Beware cache stampede
    • ESI must have a TTL greater than the parent page
    • Only implements a subset of ESI
    • Shared cache consider using s-maxage with max-age

    View Slide

  62. STALE WHILE
    Maintain a compromised UI while resolving content

    View Slide

  63. ALTERNATE WHILE
    Provide alternate content will content is being resolved

    View Slide

  64. ESI ANTI PATTERNS

    View Slide

  65. MAGNIFY THE LOAD
    Multiple ESI requests in a page all directed at the same application
    Client
    Browser
    Varnish
    Port 80
    Backend
    Apache
    Port 8080

    View Slide

  66. CACHE BUSTING
    Static assets that out stay their welcome

    View Slide

  67. REFERENCES
    http://bitly.com/pw3HXm

    View Slide

  68. IMAGE CREDITS
    http://www.flickr.com/photos/bondgirly/4520060395/sizes/o/in/
    photostream/

    View Slide

  69. THANK YOU!
    • Email: [email protected]
    • Skype: astead-ibuildings
    • Twitter: @alistairstead

    View Slide

  70. QUESTIONS?
    http://joind.in/3591

    View Slide

  71. WE ARE HIRING!
    http://www.ibuildings.co.uk/about/careers/

    View Slide