Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

When dynamic becomes static - the next step in web caching techniques

958 views

Published on

Although tools like Varnish can improve performance and scalability for static sites, when user-specific content is needed, a hit to the PHP/Ruby/Python/.Net backend is still required, causing scalability issues. We’ll look at a brand-new Nginx module which implements an ultra-fast and scalable solution to this problem, changing the way developers think about designing sites with user-specific content.

Published in: Technology
  • Be the first to comment

When dynamic becomes static - the next step in web caching techniques

  1. 1. When dynamic becomes static (the next step in web caching techniques) Wim Godden Cu.be Solutions @wimgtr
  2. 2. Who am I ? Wim Godden (@wimgtr) Founder of Cu.be Solutions (http://cu.be) Open Source developer since 1997 Developer of OpenX, PHPCompatibility, PHPConsistent, ... Speaker at Open Source conferences
  3. 3. Who are you ? Developers ? System/network engineers ? Managers ?
  4. 4. Quick note Whenever you see feel free to think
  5. 5. To understand the present Understand the past
  6. 6. The Stone Age New blog post by : caveman003
  7. 7. Pre-dynamic : draw it and make html
  8. 8. The Egyptian Era
  9. 9. Old-school dynamic : 'rebuild-every-time'
  10. 10. The Industrial Revolution
  11. 11. Dynamic : let's cache
  12. 12. Dynamic : let's cache
  13. 13. Dynamic : let's cache
  14. 14. Extra ! Extra !
  15. 15. Dynamic content in static content
  16. 16. Dynamic content in static content
  17. 17. Dynamic content in static content
  18. 18. The Modern Era
  19. 19. More load, more webservers
  20. 20. More load, more webservers
  21. 21. More load, more webservers
  22. 22. More load, more webservers
  23. 23. More load, more webservers
  24. 24. More load, more webservers
  25. 25. More load, more webservers
  26. 26. Pushing updates to cache
  27. 27. Today
  28. 28. Adding reverse proxy caching
  29. 29. Adding reverse proxy caching
  30. 30. Typical website structure Header Latest news Article content page Page content Navigation
  31. 31. Caching blocks with individual TTLs Top header (cache for 2h) Latest news Article content page Page content Navigation (cache for 1h)
  32. 32. Caching blocks with individual cache duration Top header (cache for 2h) Latest news (cache for 2m) Article content page Page content (cache for 30m) Navigation (cache for 1h)
  33. 33. ESI – how it works GET /page GET /page
  34. 34. ESI – how it works GET /page GET /page <html> ... <esi:include src="/top"/> <esi:include src="/nav"/> <div id=”something”> <esi:include src="/latest-news"/> </div> <esi:include src="/article/id/732"/> ... </html>
  35. 35. ESI – how it works GET /top <div id=”top-part”> <a href=”/login”>Login</a> </div>
  36. 36. ESI – how it works GET /page GET /page <html> ... <esi:include src="/top"/> <esi:include src="/nav"/> <div id=”something”> <esi:include src="/latest-news"/> </div> <esi:include src="/article/id/732"/> ... </html>
  37. 37. ESI – how it works GET /page GET /page <html> ... <div id=”top-part”> <a href=”/login”>Login</a> </div> <esi:include src="/nav"/> <div id=”something”> <esi:include src="/latest-news"/> </div> <esi:include src="/article/id/732"/> ... </html>
  38. 38. Varnish - what can/can't be cached ? Can : Static pages Images, js, css Static parts of pages that don't change often (ESI) Can't : POST requests Very large files (it's not a file server !) Requests with Set-Cookie User-specific content
  39. 39. ESI → no caching on user-specific content ? Logged in as : Wim Godden 5 messages cache for cache for 5min 1h cache for 0s ?
  40. 40. Error... does not compute !
  41. 41. Back in 2010
  42. 42. Avoid hitting the backend GET /page DB
  43. 43. No more backend GET /page + SLIC
  44. 44. Requesting /page (1st time) Nginx Shared memory 1 2 3 4 /page /page
  45. 45. Requesting /page SLIC subrequests (1st time) Nginx 1 2 3 /menu /news /top (with session cookie) /menu /news /top (in SLIC session)
  46. 46. Requesting /page (next time) Nginx Shared memory 1 2 /page /page /menu /news /top (in SLIC session)
  47. 47. SLIC on Nginx <slic:include key="top" src="/top" session="true" /> <slic:include key="news" src="/news" /> <slic:include key="menu" src="/menu" /> Logged in as : Wim Godden 5 messages ???
  48. 48. New message is sent... POST /send DB insert into... set(...) top (in SLIC session)
  49. 49. Advantages No repeated GET hits to webserver anymore ! At login : POST → warm up the cache ! No repeated hits for user-specific content Not even for non-specific content
  50. 50. News added addnews() method DB insert into... set(...) Memcache key /news
  51. 51. First release : ESI Part of the ESI 1.0 spec Only relevant features implemented Extension for dynamic session support But : unavailable for copyright reasons
  52. 52. Rebuilt from scratch : SLIC Control structures : if/else, switch/case, foreach Variable handling Strings : concatenation, substring, … Exception handling, header manipulation, … JSON support !
  53. 53. SLIC code samples You are logged in as : <slic:session_var("person_name") />
  54. 54. SLIC code samples <slic:switch var="session_var('isAdmin')"> <slic:case value="1"> <slic:include key="admin-buttons" src="/admin-buttons.php" /> </slic:case> <slic:default> <div id="just-a-user"> <slic:include key="user-buttons" src="/user-buttons.php" /> </div> </slic:default> </slic:switch>
  55. 55. SLIC code samples <slic:foreach item="messageId" src="global_var('thread' + query_var('threadId'))"> <slic:include key="'thread-message_' + messageId" src="'/thread/message.php?id=' + messageId" /> </slic:foreach>
  56. 56. Approaches – full block <p id=”LoggedInAs”> You are logged in as : Wim Godden </p> <p id=”MessageCount”> You have 5 messages </p> Logged in as : Wim Godden 5 messages <slic:include key="top" src="/top" session="true" /> top_432
  57. 57. Approaches – individual variables Logged in as : Wim Godden <p id=”LoggedInAs”> You are logged in as : <slic:session_var("person_name") /> </p> <p id=”MessageCount”> You have <slic:session_var(“messages”) /> messages </p> 5 messages <slic:include key="top" src="/top" session="true" />
  58. 58. Approaches – JSON Logged in as : Wim Godden 5 messages <slic:include key="top" src="/top" session="true" /> <p id=”LoggedInAs”> You are logged in as : <slic:session_var("userData").person_name /> </p> <p id=”MessageCount”> You have <slic:session_var(“userData”).message_count /> messages </p>
  59. 59. Identifying the user In Nginx configuration : slic_session_cookie <name> → Defined by language (or configurable) slic_session_identifier <string> → Defined by you Example for PHP : slic_session_cookie PHPSESSID slic_session_identifier UserID
  60. 60. Identifying the user Cookie : PHPSESSID = jpsidc1po35sq9q3og4f3hi6e2 Nginx + SLIC 4g3e2t UserID_jpsidc1po35sq9q3og4f3hi6e2
  61. 61. Retrieving user specific content Nginx + SLIC get userData_432 Cookie : PHPSESSID = jpsidc1po35sq9q3og4f3hi6e2
  62. 62. What's the result ?
  63. 63. Figures 2nd customer : No. of web servers : 72 → 8 No. of db servers : 15 → 4 Total : 87 → 12 (86% reduction !) Last customer : No. of total servers : +/- 1350 Expected reduction : 1350 → 380 Expected savings : €1.5 Million per year
  64. 64. Why is it so much faster ?
  65. 65. Code changes Required Template conversion Push-to-DB → Push-to-DB + Push-to-Cache Choice : If user is logged in → push updates to cache If user is not logged in → warm up cache on login
  66. 66. Availability Good news : The concept is solid : ESI version stable at 4 customers Open Source Bad news : First customer holds copyrights Total rebuild Q2 2015 : v0.1 (include, variable handling, …) Final release : Q3 2015 Site : http://slic.cu.be Code : Github
  67. 67. Some technical details Written in Lua (with LuaJIT) Each SLIC:include is a subrequest Groups cache key requests together for multiget Shares cache results across all subrequests Memcached implemented Redis and others in the pipeline Not RFC compliant yet Unit tested Future (1.0 or beyond) : Better cache abstraction Template compilation Translation functionality ...
  68. 68. So...
  69. 69. Questions ?
  70. 70. Questions ?
  71. 71. Thanks ! @wimgtr wim@cu.be

×