SlideShare a Scribd company logo
1 of 72
Download to read offline
When dynamic becomes static
(the next step in web caching techniques)
Wim Godden
Cu.be Solutions
@wimgtr
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 OpenX, PHPCompatibility, PHPConsistent, ...
Speaker at Open Source conferences
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
Extra ! Extra !
Dynamic content in static content
The Modern Era
More load, more webservers
Pushing updates to cache
Today
Adding reverse proxy caching
Typical website structure
Article content page
Page content
Header
Latest news
Navigation
Caching blocks with individual TTLs
Article content page
Page content
Top header
(TTL = 2h)
Latest news
Navigation
(TTL = 1h)
Caching blocks with individual TTLs
Article content page
Page content (TTL = 30m)
Top header
(TTL = 2h)
Latest news (TTL = 2m)
Navigation
(TTL = 1h)
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="/latest-news"/>
</div>
<esi:include src="/article/id/732"/>
...
</html>
GET /pageGET /page
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="/latest-news"/>
</div>
<esi:include src="/article/id/732"/>
...
</html>
GET /pageGET /page
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
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
ESI → no caching on user-specific content ?
Logged in as : Wim Godden
5 messages
TTL = 5minTTL=1h
TTL = 0s ?
Error... does not compute !
The semi-functional Varnish way
Use VCL to attach session id or UUID to cache entries
if( req.http.Cookie ~ "myapp_unique_user_id" ) {
set req.http.X-Varnish-Hashed-On =
regsub( req.http.Cookie, "^.*?
myapp_unique_user_id=([^;]*);*.*$", "1" );
}
Painful, messy configuration
Inefficient and messy way to update data
POST /sendmessagePOST /sendmessage
PURGE /top?UUID
GET /page GET /top?UUID
DB
The almost functional Varnish way
Varnish module : VMOD-Memcached
Connects Varnish directly to Memcached
Advantage :
It works
It will speed a few things up
Disadvantage :
A pain to set up
No plug&play → DIY !
Only works on info stored in session
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
<html>
...
<slic:include src="/top" key=”top” session=”true”/>
<slic:include src="/nav" key=”nav”/>
<slic:include src="/article/id/732" key=”article732”/>
...
</html>
Requesting /page SLIC subrequests (1st
time)
Nginx
1
2
3
/nav
/article732
/top (in SLIC session)
/nav
/article/id/732
/top (with session cookie)
Requesting /page (next time)
Nginx
Shared memory
1
2
/page
/nav
/article732
/top (in SLIC session)
/page
SLIC on Nginx
<slic:include key="article732" src="/article/732" />
<slic:include
key="nav"
src="/nav" />
<slic:include key="top" src="/top" session="true" />
Logged in as : Wim Godden
5 messages ???
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-specific content
Not even for non-specific content
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
But : unavailable for copyright reasons
Rebuilt from scratch : SLIC
Control structures : if/else, switch/case, foreach
Variable handling
Strings : concatenation, substring, …
Exception handling, header manipulation, …
JSON support !
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" 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>
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>
Approaches – full block
<p id=”LoggedInAs”>
You are logged in as : Wim Godden
</p>
<p id=”MessageCount”>
5 messages
</p>
Logged in as : Wim Godden
5 messages
top_432
Approaches – individual variables
<p id=”LoggedInAs”>
You are logged in as : <slic:session_var("person_name") />
</p>
<p id=”MessageCount”>
<slic:session_var(“messages”) /> messages
</p>
Logged in as : Wim Godden
5 messages
Approaches – JSON
<p id=”LoggedInAs”>
You are logged in as : <slic:session_var("userData").person_name />
</p>
<p id=”MessageCount”>
<slic:session_var(“userData”).message_count /> messages
</p>
Logged in as : Wim Godden
5 messages
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
Identifying the user
Nginx + SLIC
Cookie :
PHPSESSID =
jpsidc1po35sq9q3og4f3hi6e2
get UserID_jpsidc1po35sq9q3og4f3hi6e2432
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 customer :
No. of total servers : +/- 1350
Expected reduction : 1350 → 380
Expected savings : €1.5 Million per year
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 → push updates to cache
If user is not logged in → warm up cache on login
Availability
Good news :
The concept is solid : ESI version stable at 4 customers
Open Source
Bad news :
First customer holds copyrights
Total rebuild
March : v0.1 (include, variable handling, …)
Final release : Q2-3 2015 (?)
Site : http://slic.cu.be
Code : Github
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
Template compilation (!!)
Memcached implemented
Redis and others in the pipeline
Not RFC compliant yet
Unit tested
Future (1.0 or beyond) :
Translation functionality
...
So...
Questions ?
Questions ?
Thanks !
@wimgtr
wim@cu.be
Please provide some feedback : http://joind.in/13203

More Related Content

What's hot

Remove php calls and scale your site like crazy !
Remove php calls and scale your site like crazy !Remove php calls and scale your site like crazy !
Remove php calls and scale your site like crazy !Wim Godden
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practicesSultan Khan
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWim Godden
 
HTML5 Web Messaging
HTML5 Web MessagingHTML5 Web Messaging
HTML5 Web MessagingMike Taylor
 
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao PauloHTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao PauloRobert Nyman
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaRobert Nyman
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Scriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillScriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillMario Heiderich
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloJavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloRobert Nyman
 
I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)xsist10
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for youSimon Willison
 
I put on my mink and wizard behat (talk)
I put on my mink and wizard behat (talk)I put on my mink and wizard behat (talk)
I put on my mink and wizard behat (talk)xsist10
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeWim Godden
 
Nginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your siteNginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your siteWim Godden
 
Cookies and sessions
Cookies and sessionsCookies and sessions
Cookies and sessionsUdaAs PaNchi
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJSSylvain Zimmer
 

What's hot (18)

Remove php calls and scale your site like crazy !
Remove php calls and scale your site like crazy !Remove php calls and scale your site like crazy !
Remove php calls and scale your site like crazy !
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practices
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniques
 
HTML5 Web Messaging
HTML5 Web MessagingHTML5 Web Messaging
HTML5 Web Messaging
 
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao PauloHTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Scriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the SillScriptless Attacks - Stealing the Pie without touching the Sill
Scriptless Attacks - Stealing the Pie without touching the Sill
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloJavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
 
I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
I put on my mink and wizard behat (talk)
I put on my mink and wizard behat (talk)I put on my mink and wizard behat (talk)
I put on my mink and wizard behat (talk)
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
 
Nanoc
NanocNanoc
Nanoc
 
Nginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your siteNginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your site
 
iCloud keychain
iCloud keychainiCloud keychain
iCloud keychain
 
Cookies and sessions
Cookies and sessionsCookies and sessions
Cookies and sessions
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 

Similar to When dynamic becomes static

When dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniquesWhen dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniquesWim Godden
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes staticWim Godden
 
When dynamic becomes static - the next step in web caching techniques
When dynamic becomes static - the next step in web caching techniquesWhen dynamic becomes static - the next step in web caching techniques
When dynamic becomes static - the next step in web caching techniquesWim Godden
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websocketsWim Godden
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalabilityWim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websocketsWim Godden
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup PerformanceGreg Whalin
 
DACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdf
DACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdfDACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdf
DACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdfDNUG e.V.
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
Die ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web AdministratorenDie ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web Administratorenpanagenda
 
The Ultimate Administrator’s Guide to HCL Nomad Web
The Ultimate Administrator’s Guide to HCL Nomad WebThe Ultimate Administrator’s Guide to HCL Nomad Web
The Ultimate Administrator’s Guide to HCL Nomad Webpanagenda
 
Fix me if you can - DrupalCon prague
Fix me if you can - DrupalCon pragueFix me if you can - DrupalCon prague
Fix me if you can - DrupalCon praguehernanibf
 
Lecture 11 - PHP - Part 5 - CookiesSessions.ppt
Lecture 11 - PHP - Part 5 - CookiesSessions.pptLecture 11 - PHP - Part 5 - CookiesSessions.ppt
Lecture 11 - PHP - Part 5 - CookiesSessions.pptSreejithVP7
 
Collect distributed application logging using fluentd (EFK stack)
Collect distributed application logging using fluentd (EFK stack)Collect distributed application logging using fluentd (EFK stack)
Collect distributed application logging using fluentd (EFK stack)Marco Pas
 
High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”
High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”
High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”Valent Mustamin
 

Similar to When dynamic becomes static (20)

When dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniquesWhen dynamic becomes static : the next step in web caching techniques
When dynamic becomes static : the next step in web caching techniques
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
 
When dynamic becomes static - the next step in web caching techniques
When dynamic becomes static - the next step in web caching techniquesWhen dynamic becomes static - the next step in web caching techniques
When dynamic becomes static - the next step in web caching techniques
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniques
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
 
DACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdf
DACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdfDACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdf
DACHNUG50 EVERYTHING-you-need-to-know-about-HCL-Nomad-Web.pdf
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
Die ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web AdministratorenDie ultimative Anleitung für HCL Nomad Web Administratoren
Die ultimative Anleitung für HCL Nomad Web Administratoren
 
The Ultimate Administrator’s Guide to HCL Nomad Web
The Ultimate Administrator’s Guide to HCL Nomad WebThe Ultimate Administrator’s Guide to HCL Nomad Web
The Ultimate Administrator’s Guide to HCL Nomad Web
 
Optimizing wp
Optimizing wpOptimizing wp
Optimizing wp
 
Fix me if you can - DrupalCon prague
Fix me if you can - DrupalCon pragueFix me if you can - DrupalCon prague
Fix me if you can - DrupalCon prague
 
Lecture 11 - PHP - Part 5 - CookiesSessions.ppt
Lecture 11 - PHP - Part 5 - CookiesSessions.pptLecture 11 - PHP - Part 5 - CookiesSessions.ppt
Lecture 11 - PHP - Part 5 - CookiesSessions.ppt
 
Collect distributed application logging using fluentd (EFK stack)
Collect distributed application logging using fluentd (EFK stack)Collect distributed application logging using fluentd (EFK stack)
Collect distributed application logging using fluentd (EFK stack)
 
High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”
High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”
High Performance Wordpress: “Faster, Cheaper, Easier : Pick Three”
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 

More from Wim Godden

Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to lifeWim Godden
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8Wim Godden
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to lifeWim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developersWim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.xWim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.xWim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developersWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Practical git for developers
Practical git for developersPractical git for developers
Practical git for developersWim Godden
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Wim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 

More from Wim Godden (20)

Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Practical git for developers
Practical git for developersPractical git for developers
Practical git for developers
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 

When dynamic becomes static

  • 1. When dynamic becomes static (the next step in web caching techniques) Wim Godden Cu.be Solutions @wimgtr
  • 2. Who am I ? Wim Godden (@wimgtr)
  • 11. Belgium – the traffic
  • 12. 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
  • 13. Who are you ? Developers ? System/network engineers ? Managers ?
  • 14. Quick note Whenever you see feel free to think
  • 15. To understand the present Understand the past
  • 16. The Stone Age New blog post by : caveman003
  • 17. Pre-dynamic : draw it and make html
  • 19. Old-school dynamic : 'rebuild-every-time'
  • 23. Dynamic content in static content
  • 25. More load, more webservers
  • 27. Today
  • 29. Typical website structure Article content page Page content Header Latest news Navigation
  • 30. Caching blocks with individual TTLs Article content page Page content Top header (TTL = 2h) Latest news Navigation (TTL = 1h)
  • 31. Caching blocks with individual TTLs Article content page Page content (TTL = 30m) Top header (TTL = 2h) Latest news (TTL = 2m) Navigation (TTL = 1h)
  • 32. ESI – how it works GET /pageGET /page
  • 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. ESI – how it works <div id=”top-part”> <a href=”/login”>Login</a> </div> GET /top
  • 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. 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. 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
  • 38. ESI → no caching on user-specific content ? Logged in as : Wim Godden 5 messages TTL = 5minTTL=1h TTL = 0s ?
  • 39. Error... does not compute !
  • 40. The semi-functional Varnish way Use VCL to attach session id or UUID to cache entries if( req.http.Cookie ~ "myapp_unique_user_id" ) { set req.http.X-Varnish-Hashed-On = regsub( req.http.Cookie, "^.*? myapp_unique_user_id=([^;]*);*.*$", "1" ); } Painful, messy configuration Inefficient and messy way to update data POST /sendmessagePOST /sendmessage PURGE /top?UUID GET /page GET /top?UUID DB
  • 41. The almost functional Varnish way Varnish module : VMOD-Memcached Connects Varnish directly to Memcached Advantage : It works It will speed a few things up Disadvantage : A pain to set up No plug&play → DIY ! Only works on info stored in session
  • 43. Avoid hitting the backend GET /page DB
  • 44. No more backend GET /page + SLIC
  • 45. Requesting /page (1st time) Nginx Shared memory 1 2 3 4 /page /page <html> ... <slic:include src="/top" key=”top” session=”true”/> <slic:include src="/nav" key=”nav”/> <slic:include src="/article/id/732" key=”article732”/> ... </html>
  • 46. Requesting /page SLIC subrequests (1st time) Nginx 1 2 3 /nav /article732 /top (in SLIC session) /nav /article/id/732 /top (with session cookie)
  • 47. Requesting /page (next time) Nginx Shared memory 1 2 /page /nav /article732 /top (in SLIC session) /page
  • 48. SLIC on Nginx <slic:include key="article732" src="/article/732" /> <slic:include key="nav" src="/nav" /> <slic:include key="top" src="/top" session="true" /> Logged in as : Wim Godden 5 messages ???
  • 49. New message is sent... POST /send DB insert into... set(...) top (in SLIC session)
  • 50. 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
  • 51. News added addnews() method DB insert into... set(...) Memcache key /news
  • 52. First release : ESI Part of the ESI 1.0 spec Only relevant features implemented Extension for dynamic session support But : unavailable for copyright reasons
  • 53. Rebuilt from scratch : SLIC Control structures : if/else, switch/case, foreach Variable handling Strings : concatenation, substring, … Exception handling, header manipulation, … JSON support !
  • 54. SLIC code samples You are logged in as : <slic:session_var("person_name") />
  • 55. 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>
  • 56. 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>
  • 57. Approaches – full block <p id=”LoggedInAs”> You are logged in as : Wim Godden </p> <p id=”MessageCount”> 5 messages </p> Logged in as : Wim Godden 5 messages top_432
  • 58. Approaches – individual variables <p id=”LoggedInAs”> You are logged in as : <slic:session_var("person_name") /> </p> <p id=”MessageCount”> <slic:session_var(“messages”) /> messages </p> Logged in as : Wim Godden 5 messages
  • 59. Approaches – JSON <p id=”LoggedInAs”> You are logged in as : <slic:session_var("userData").person_name /> </p> <p id=”MessageCount”> <slic:session_var(“userData”).message_count /> messages </p> Logged in as : Wim Godden 5 messages
  • 60. 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
  • 61. Identifying the user Nginx + SLIC Cookie : PHPSESSID = jpsidc1po35sq9q3og4f3hi6e2 get UserID_jpsidc1po35sq9q3og4f3hi6e2432
  • 62. Retrieving user specific content Nginx + SLIC get userData_432 Cookie : PHPSESSID = jpsidc1po35sq9q3og4f3hi6e2
  • 64. 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
  • 65. Why is it so much faster ?
  • 66. 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
  • 67. Availability Good news : The concept is solid : ESI version stable at 4 customers Open Source Bad news : First customer holds copyrights Total rebuild March : v0.1 (include, variable handling, …) Final release : Q2-3 2015 (?) Site : http://slic.cu.be Code : Github
  • 68. 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 Template compilation (!!) Memcached implemented Redis and others in the pipeline Not RFC compliant yet Unit tested Future (1.0 or beyond) : Translation functionality ...
  • 69. So...
  • 72. Thanks ! @wimgtr wim@cu.be Please provide some feedback : http://joind.in/13203