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) 
Wim Godden 
Cu.be Solutions 
@wimgtr
Who am I ? 
Wim Godden (@wimgtr) 
Founder of Cu.be Solutions (http://cu.be) 
Open Source developer since 1997 
Developer o...
Who are you ? 
Developers ? 
System/network engineers ? 
Managers ?
Quick note 
Whenever you see 
feel free to think
To understand the present 
Understand the past
The Stone Age 
New blog post by : caveman003
Pre-dynamic : draw it and make html
The Egyptian Era
Old-school dynamic : 'rebuild-every-time'
The Industrial Revolution
Dynamic : let's cache
Dynamic : let's cache
Dynamic : let's cache
Extra ! Extra !
Dynamic content in static content
Dynamic content in static content
Dynamic content in static content
The Modern Era
More load, more webservers
More load, more webservers
More load, more webservers
More load, more webservers
More load, more webservers
More load, more webservers
More load, more webservers
Pushing updates to cache
Today
Adding reverse proxy caching
Adding reverse proxy caching
Typical website structure 
Header 
Latest news 
Article content page 
Page content 
Navigation
Caching blocks with individual TTLs 
Top header 
(cache for 2h) 
Latest news 
Article content page 
Page content 
Navigati...
Caching blocks with individual cache duration 
Top header 
(cache for 2h) 
Latest news (cache for 2m) 
Article content pag...
ESI – how it works 
GET /page GET /page
ESI – how it works 
GET /page GET /page 
<html> 
... 
<esi:include src="/top"/> 
<esi:include src="/nav"/> 
<div id=”somet...
ESI – how it works 
GET /top 
<div id=”top-part”> 
<a href=”/login”>Login</a> 
</div>
ESI – how it works 
GET /page GET /page 
<html> 
... 
<esi:include src="/top"/> 
<esi:include src="/nav"/> 
<div id=”somet...
ESI – how it works 
GET /page GET /page 
<html> 
... 
<div id=”top-part”> 
<a href=”/login”>Login</a> 
</div> 
<esi:includ...
Varnish - what can/can't be cached ? 
Can : 
Static pages 
Images, js, css 
Static parts of pages that don't change often ...
ESI → no caching on user-specific content ? 
Logged in as : Wim Godden 
5 messages 
cache for cache for 5min 
1h 
cache fo...
Error... does not compute !
Back in 2010
Avoid hitting the backend 
GET /page 
DB
No more backend 
GET /page 
+ SLIC
Requesting /page (1st time) 
Nginx 
Shared memory 
1 
2 
3 
4 
/page 
/page
Requesting /page SLIC subrequests (1st time) 
Nginx 
1 
2 
3 
/menu 
/news 
/top (with session cookie) 
/menu 
/news 
/top...
Requesting /page (next time) 
Nginx 
Shared memory 1 
2 
/page 
/page 
/menu 
/news 
/top (in SLIC session)
SLIC on Nginx 
<slic:include key="top" src="/top" session="true" /> 
<slic:include key="news" src="/news" /> 
<slic:includ...
New message is sent... 
POST /send 
DB 
insert into... 
set(...) 
top (in SLIC session)
Advantages 
No repeated GET hits to webserver anymore ! 
At login : POST → warm up the cache ! 
No repeated hits for user-...
News added 
addnews() method 
DB 
insert into... 
set(...) 
Memcache key /news
First release : ESI 
Part of the ESI 1.0 spec 
Only relevant features implemented 
Extension for dynamic session support 
...
Rebuilt from scratch : SLIC 
Control structures : if/else, switch/case, foreach 
Variable handling 
Strings : concatenatio...
SLIC code samples 
You are logged in as : <slic:session_var("person_name") />
SLIC code samples 
<slic:switch var="session_var('isAdmin')"> 
<slic:case value="1"> 
<slic:include key="admin-buttons" sr...
SLIC code samples 
<slic:foreach item="messageId" src="global_var('thread' + query_var('threadId'))"> 
<slic:include key="...
Approaches – full block 
<p id=”LoggedInAs”> 
You are logged in as : Wim Godden 
</p> 
<p id=”MessageCount”> 
You have 5 m...
Approaches – individual variables 
Logged in as : Wim Godden 
<p id=”LoggedInAs”> 
You are logged in as : <slic:session_va...
Approaches – JSON 
Logged in as : Wim Godden 
5 messages 
<slic:include key="top" src="/top" session="true" /> 
<p id=”Log...
Identifying the user 
In Nginx configuration : 
slic_session_cookie <name> → Defined by language (or configurable) 
slic_s...
Identifying the user 
Cookie : 
PHPSESSID = 
jpsidc1po35sq9q3og4f3hi6e2 
Nginx + SLIC 
4g3e2t UserID_jpsidc1po35sq9q3og4f3...
Retrieving user specific content 
Nginx + SLIC 
get userData_432 
Cookie : 
PHPSESSID = 
jpsidc1po35sq9q3og4f3hi6e2
What's the result ?
Figures 
2nd customer : 
No. of web servers : 72 → 8 
No. of db servers : 15 → 4 
Total : 87 → 12 (86% reduction !) 
Last ...
Why is it so much faster ?
Code changes 
Required 
Template conversion 
Push-to-DB → Push-to-DB + Push-to-Cache 
Choice : 
If user is logged in → pus...
Availability 
Good news : 
The concept is solid : ESI version stable at 4 customers 
Open Source 
Bad news : 
First custom...
Some technical details 
Written in Lua (with LuaJIT) 
Each SLIC:include is a subrequest 
Groups cache key requests togethe...
So...
Questions ?
Questions ?
Thanks ! 
@wimgtr 
wim@cu.be
You’ve finished this document.
Download and read it offline.
Upcoming SlideShare
Improve App Performance & Reliability with NGINX Amplify
Next
Upcoming SlideShare
Improve App Performance & Reliability with NGINX Amplify
Next
Download to read offline and view in fullscreen.

3

Share

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

Download to read offline

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.

Related Books

Free with a 30 day trial from Scribd

See all

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
  • isbkch

    Feb. 19, 2015
  • varnishJos

    Nov. 28, 2014
  • vinsonzou

    Nov. 24, 2014

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.

Views

Total views

1,046

On Slideshare

0

From embeds

0

Number of embeds

3

Actions

Downloads

21

Shares

0

Comments

0

Likes

3

×