When dynamic becomes static – the next
step in web caching techniques
Wim Godden
Cu.be Solutions
Disclaimer
The next step
As in : what you will be doing in the future
Not as in : go home and run it ;-)
Language of choic...
Who am I ?
Wim Godden (@wimgtr)
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
My town
My town
Belgium – the traffic
Who am I ?
Wim Godden (@wimgtr)
Founder of Cu.be Solutions (http://cu.be)
Open Source developer since 1997
Developer of Op...
Who are you ?
Developers ?
System/network engineers ?
Managers ?
To understand the present
Understand the past
The Stone Age
New blog post by : caveman003
Pre-PHP : draw it and make html
The Egyptian Era
Old-school PHP : 'rebuild-every-time'
The Industrial Revolution
PHP : let's cache
Extra ! Extra !
PHP : dynamic content in static content
The Modern Era
PHP : multiple webservers
PHP : push updates to cache
Today
Adding reverse proxy caching
Website with ESI
Article content page
Page content
Header
Latest news
Navigation
Website with ESI
Article content page
Page content
Top header
(TTL = 2h)
Latest news
Navigation
(TTL = 1h)
Website with ESI
Article content page
Page content (TTL = 30m)
Top header
(TTL = 2h)
Latest news (TTL = 2m)
Navigation
(TT...
ESI – how it works
GET /pageGET /page
ESI – how it works
<html>
...
<esi:include src="/top"/>
<esi:include src="/nav"/>
<div id=”something”>
<esi:include src="/...
ESI – how it works
<div id=”top-part”>
<a href=”/login”>Login</a>
</div>
GET /top
ESI – how it works
<html>
...
<esi:include src="/top"/>
<esi:include src="/nav"/>
<div id=”something”>
<esi:include src="/...
ESI – how it works
<html>
...
<div id=”top-part”>
<a href=”/login”>Login</a>
</div>
<esi:include src="/nav"/>
<div id=”som...
Going to /page/id/732
<html>
<esi:include src="/top"/>
<esi:include src="/nav"/>
<div id="something">
<esi:include src="/l...
Article content page
<esi:include src="/article/732"/>
Varnish - ESI
<esi:include src="/top"/>
<esi:include src="/news"/>
...
Varnish - what can/can't be cached ?
Can :
Static pages
Images, js, css
Static parts of pages that don't change often (ESI...
ESI → no caching on user-specific content ?
Logged in as : Wim Godden
5 messages
TTL = 5minTTL=1h
TTL = 0s ?
Nginx
Web server
Reverse proxy
Lightweight, fast
13.46% of all Websites
Nginx
No threads, event-driven
Uses epoll / kqueue
Low memory footprint
10000 active connections = normal
ESI on Nginx
Logged in as : Wim Godden
5 messages
NEWSMenu
ESI SLIC on Nginx
<slic:include key="news" src="/news" />
<slic:include
key="menu"
src="/menu" />
<slic:include key="top" ...
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 (in SLIC session)
Requesting /page (next time)
Nginx
Shared memory
1
2
/page
/menu
/news
/top (in SLIC session)
/page
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-spe...
News added
addnews() method
DB
insert into...
set(...)
Memcache key /news
Advantages
No repeated GET hits to webserver anymore !
At login : POST → warm up the cache !
No repeated hits for user-spe...
How many Memcached requests ?
Logged in as : Wim Godden
5 messages
<slic:include key="news" src="/news" />
<slic:include
k...
First release : ESI
Part of the ESI 1.0 spec
Only relevant features implemented
Extension for dynamic session support
But ...
Rebuilt from scratch : SLIC
Control structures : if/else, switch/case, foreach
Variable handling
Strings : concatenation, ...
SLIC code samples
You are logged in as : <slic:session_var("person_name") />
You are logged in as : <@s("person_name") />
SLIC code samples
<slic:switch var="session_var('isAdmin')">
<slic:case value="1">
<slic:include key="admin-buttons" src="...
SLIC code samples
<slic:foreach item="messageId" src="global_var('thread' + query_var('threadId'))">
<slic:include key="'t...
Approaches – full block
<p id=”LoggedInAs”>
You are logged in as : <slic:session_var("person_name") />
</p>
<p id=”Message...
Approaches – individual variables
<p id=”LoggedInAs”>
You are logged in as : <slic:session_var("person_name") />
</p>
<p i...
Approaches – JSON
<p id=”LoggedInAs”>
You are logged in as : <slic:session_var("userData").person_name />
</p>
<p id=”Mess...
Identifying the user
In Nginx configuration :
slic_session_cookie <name> → Defined by language (or configurable)
slic_sess...
Identifying the user
Nginx + SLIC
Cookie :
PHPSESSID =
jpsidc1po35sq9q3og4f3hi6e2
get UID_jpsidc1po35sq9q3og4f3hi6e2432
Retrieving user specific content
Nginx + SLIC
Cookie :
PHPSESSID =
jpsidc1po35sq9q3og4f3hi6e2
get userData_432
Why Nginx ?
Native Memcached support
Excellent and superfast subrequest system
Including parallel subrequests
Handles thou...
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 custo...
Why is it so much faster ?
A real example : vBulletin
A real example : vBulletin
Post
isModerator session variable
isAdmin session variable
A real example : vBulletin
DB Server Load Web Server Load Max Requests/sec (1 = 282)
0
5
10
15
20
25
30
35
Standard instal...
Code changes
Required
Template conversion
Push-to-DB → Push-to-DB + Push-to-Cache
Choice :
If user is logged in → push upd...
Availability
Good news :
It will become Open Source
It's solid : ESI version stable at 4 customers
PHP version (currently ...
So...
Questions ?
Questions ?
Contact
Twitter @wimgtr
Web http://techblog.wimgodden.be
Slides http://www.slideshare.net/wimg
E-mail wim.godden@cu.be
Upcoming SlideShare
Loading in …5
×

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

2,478 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
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,478
On SlideShare
0
From Embeds
0
Number of Embeds
10
Actions
Shares
0
Downloads
23
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

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
  2. 2. Disclaimer The next step As in : what you will be doing in the future Not as in : go home and run it ;-) Language of choice : PHP But : think Perl, Python, Ruby, Java, .Net, …
  3. 3. Who am I ? Wim Godden (@wimgtr)
  4. 4. Where I'm from
  5. 5. Where I'm from
  6. 6. Where I'm from
  7. 7. Where I'm from
  8. 8. Where I'm from
  9. 9. Where I'm from
  10. 10. My town
  11. 11. My town
  12. 12. Belgium – the traffic
  13. 13. Who am I ? Wim Godden (@wimgtr) Founder of Cu.be Solutions (http://cu.be) Open Source developer since 1997 Developer of OpenX, PHPCompatibility, ... Speaker at PHP and Open Source conferences
  14. 14. Who are you ? Developers ? System/network engineers ? Managers ?
  15. 15. To understand the present Understand the past
  16. 16. The Stone Age New blog post by : caveman003
  17. 17. Pre-PHP : draw it and make html
  18. 18. The Egyptian Era
  19. 19. Old-school PHP : 'rebuild-every-time'
  20. 20. The Industrial Revolution
  21. 21. PHP : let's cache
  22. 22. Extra ! Extra !
  23. 23. PHP : dynamic content in static content
  24. 24. The Modern Era
  25. 25. PHP : multiple webservers
  26. 26. PHP : push updates to cache
  27. 27. Today
  28. 28. Adding reverse proxy caching
  29. 29. Website with ESI Article content page Page content Header Latest news Navigation
  30. 30. Website with ESI Article content page Page content Top header (TTL = 2h) Latest news Navigation (TTL = 1h)
  31. 31. Website with ESI Article content page Page content (TTL = 30m) Top header (TTL = 2h) Latest news (TTL = 2m) Navigation (TTL = 1h)
  32. 32. ESI – how it works GET /pageGET /page
  33. 33. ESI – how it works <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> GET /pageGET /page
  34. 34. ESI – how it works <div id=”top-part”> <a href=”/login”>Login</a> </div> GET /top
  35. 35. ESI – how it works <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> GET /pageGET /page
  36. 36. ESI – how it works <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> GET /pageGET /page
  37. 37. Going to /page/id/732 <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>
  38. 38. Article content page <esi:include src="/article/732"/> Varnish - ESI <esi:include src="/top"/> <esi:include src="/news"/> <esi:include src="/nav"/>
  39. 39. 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
  40. 40. ESI → no caching on user-specific content ? Logged in as : Wim Godden 5 messages TTL = 5minTTL=1h TTL = 0s ?
  41. 41. Nginx Web server Reverse proxy Lightweight, fast 13.46% of all Websites
  42. 42. Nginx No threads, event-driven Uses epoll / kqueue Low memory footprint 10000 active connections = normal
  43. 43. ESI on Nginx Logged in as : Wim Godden 5 messages NEWSMenu
  44. 44. ESI SLIC on Nginx <slic:include key="news" src="/news" /> <slic:include key="menu" src="/menu" /> <slic:include key="top" src="/top" session="true" />
  45. 45. Requesting /page (1st time) Nginx Shared memory 1 2 3 4 /page /page
  46. 46. Requesting /page SLIC subrequests (1st time) Nginx 1 2 3 /menu /news /top (in SLIC session)
  47. 47. Requesting /page (next time) Nginx Shared memory 1 2 /page /menu /news /top (in SLIC session) /page
  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. 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 No TTLs for non-specific content
  52. 52. How many Memcached requests ? Logged in as : Wim Godden 5 messages <slic:include key="news" src="/news" /> <slic:include key="menu" src="/menu" /> <slic:include key="top" src="/top" session="true" />
  53. 53. First release : ESI Part of the ESI 1.0 spec Only relevant features implemented Extension for dynamic session support But : unavailable for copyright reasons
  54. 54. Rebuilt from scratch : SLIC Control structures : if/else, switch/case, foreach Variable handling Strings : concatenation, substring, … Exception handling, header manipulation, … JSON support !
  55. 55. SLIC code samples You are logged in as : <slic:session_var("person_name") /> You are logged in as : <@s("person_name") />
  56. 56. 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>
  57. 57. 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>
  58. 58. Approaches – full block <p id=”LoggedInAs”> You are logged in as : <slic:session_var("person_name") /> </p> <p id=”MessageCount”> You have 5 messages </p> Logged in as : Wim Godden 5 messages <slic:include key="top" src="/top" session="true" />
  59. 59. Approaches – individual variables <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> Logged in as : Wim Godden 5 messages <slic:include key="top" src="/top" session="true" />
  60. 60. Approaches – JSON <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> Logged in as : Wim Godden 5 messages <slic:include key="top" src="/top" session="true" />
  61. 61. 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 UID
  62. 62. Identifying the user Nginx + SLIC Cookie : PHPSESSID = jpsidc1po35sq9q3og4f3hi6e2 get UID_jpsidc1po35sq9q3og4f3hi6e2432
  63. 63. Retrieving user specific content Nginx + SLIC Cookie : PHPSESSID = jpsidc1po35sq9q3og4f3hi6e2 get userData_432
  64. 64. Why Nginx ? Native Memcached support Excellent and superfast subrequest system Including parallel subrequests Handles thousands of connections per worker With minimal memory footprint Integrates with php-fpm Additional features (chroot, slow request log, offline processing, ...) Graceful rolling upgrades
  65. 65. What's the result ?
  66. 66. 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
  67. 67. Why is it so much faster ?
  68. 68. A real example : vBulletin
  69. 69. A real example : vBulletin Post isModerator session variable isAdmin session variable
  70. 70. A real example : vBulletin DB Server Load Web Server Load Max Requests/sec (1 = 282) 0 5 10 15 20 25 30 35 Standard install With Memcached Nginx + SCL + memcached
  71. 71. 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
  72. 72. Availability Good news : It will become Open Source It's solid : ESI version stable at 4 customers PHP version (currently for dev, later for docs and learning) Bad news : First customer holds copyrights Total rebuild → Open Source release No current projects, so spare time Anyone feel like sponsoring ? Beta : Aug 14 (?) Stable : Oct 14 (?) - on Github
  73. 73. So...
  74. 74. Questions ?
  75. 75. Questions ?
  76. 76. Contact Twitter @wimgtr Web http://techblog.wimgodden.be Slides http://www.slideshare.net/wimg E-mail wim.godden@cu.be

×