You are on page 1of 94

Assembling Pages Last

Edge Caching, ESI, and Rails

Aaron Batalion

5/31/2008

Assembling Pages Last Edge Caching , ESI , and Rails Aaron Batalion 5/31/2008 1
2
2

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what?

- Edge Caching

- FragmentFu

- Deployment Options

- Pros/Cons of Edge Caching

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what?

- Edge Caching

- FragmentFu

- Deployment Options

- Pros/Cons of Edge Caching

7
7
8
8
9
9
10
10
10
11
11
12
12
13
13
http://readers.livingsocial.com 14
http://readers.livingsocial.com
http://readers.livingsocial.com
def show @feed = @person.mini_feed @current = @person.currently_reading @news =
def show @feed = @person.mini_feed @current = @person.currently_reading @news =
def show
@feed = @person.mini_feed
@current = @person.currently_reading
@news = Blog.recent_by_vertical(“readingsocial”)
end
= @person.mini_feed @current = @person.currently_reading @news = Blog.recent_by_vertical(“readingsocial”) end 15
<html> <%= render :partial => "header/login" -%> <%= render :partial =>
<html> <%= render :partial => "header/login" -%> <%= render :partial =>
<html>
<%= render :partial => "header/login" -%>
<%= render :partial => "feed" -%>
<%= render :partial => "current" -%>
<%= render :partial => "news" -%>
</html>
:partial => "current" -%> <%= render :partial => "news" -%> </html> 16
When thats not enough, then what? 17
When thats not enough, then what?
When thats not enough, then what?
When thats not enough, then what? 18
When thats not enough, then what?
When thats not enough, then what?
When thats not enough, then what? 19
When thats not enough, then what?
When thats not enough, then what?

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what?

- Edge Caching

- FragmentFu

- Deployment Options

- Pros/Cons of Edge Caching

class PeopleController caches_page :show end 21
class PeopleController caches_page :show end
class PeopleController
caches_page :show
end
class PeopleController caches_page :show end 21
class PeopleController caches_page :show end 22
class PeopleController caches_page :show end
class PeopleController
caches_page
:show
end
class PeopleController caches_action :show end 23
class PeopleController caches_action :show end
class PeopleController
caches_action :show
end
class PeopleController caches_action :show end 23
class PeopleController caches_action :show end 24
class PeopleController caches_action :show end
class PeopleController
caches_action
:show
end
<% cache(“mini-feed-#{@person.id}”) do %> <% @feed = @person.mini_feed %> <%= render :partial
<% cache(“mini-feed-#{@person.id}”) do %> <% @feed = @person.mini_feed %> <%= render :partial
<% cache(“mini-feed-#{@person.id}”) do %>
<% @feed = @person.mini_feed %>
<%= render :partial => "feed" -%>
<% end %>
<% @feed = @person.mini_feed %> <%= render :partial => "feed" -%> <% end %> 25
class Person def mini_feed cache(“feed-#{id}”) { } end end 26
class Person def mini_feed cache(“feed-#{id}”) { } end end
class Person
def mini_feed
cache(“feed-#{id}”) {
}
end
end
class Person def mini_feed cache(“feed-#{id}”) { } end end 26
When thats not enough, then what? When thats not enough 27
When thats not enough, then what? When thats not enough
When thats not enough, then what?
When thats not enough
28
28
Rails isn’t fast It is fast enough You can always get LOTS and LOTS of
Rails isn’t fast It is fast enough You can always get LOTS and LOTS of

Rails isn’t fast

It is fast enough

You can always get LOTS and LOTS of servers

Use your application Without hitting your application 30
Use your application Without hitting your application 30
Use your application Without hitting your application 30

Use your application Without hitting your application

Use your application Without hitting your application 30

HTTP/1.1 200 OK Date: Fri, 15 Dec 2007 17:32:47 GMT Content-Length: 33286 Cache-Control: max-age=7200 Content-Type: text/html

200 OK Date: Fri, 15 Dec 2007 17:32:47 GMT Content-Length: 33286 Cache-Control: max-age=7200 Content-Type: text/html 31
HTTP/1.1 200 OK Date: Fri, 15 Dec 2007 17:32:47 GMT Content-Length: 33286 Cache-Control: max-age=7200 Content-Type:
HTTP/1.1 200 OK Date: Fri, 15 Dec 2007 17:32:47 GMT Content-Length: 33286 Cache-Control: max-age=7200 Content-Type:

HTTP/1.1 200 OK Date: Fri, 15 Dec 2007 17:32:47 GMT Content-Length: 33286 Cache-Control: max-age=7200 Content-Type: text/html

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what? - Edge Caching

- FragmentFu

- Deployment Options

- Pros/Cons of Edge Caching

ESI

ESI Edge Side Includes 2001 W3C Spec http://www.w3.org/TR/esi-lang By: Akamai, Oracle, BEA, Vignette 34

Edge Side Includes

2001 W3C Spec

By: Akamai, Oracle, BEA, Vignette

simple markup language esi : include esi : invalidate esi : attempt esi : chose

simple markup language

esi:include

esi:invalidate

esi:attempt

esi:chose

esi:try

HTTP_*

esi:except

esi:when

parsed by ESI server 36

parsed by ESI server

Mongrel ESI html + esi Server Mongrel Mongrel http://readers.livingsocial.com 1. http://readers.livingsocial.com 2.
Mongrel ESI html + esi Server Mongrel Mongrel
Mongrel
ESI
html + esi
Server
Mongrel
Mongrel
Mongrel ESI html + esi Server Mongrel Mongrel http://readers.livingsocial.com 1. http://readers.livingsocial.com 2.
+ esi Server Mongrel Mongrel http://readers.livingsocial.com 1. http://readers.livingsocial.com 2. Page Template 37
1. http://readers.livingsocial.com 2. Page Template
1. http://readers.livingsocial.com
2. Page Template
4 /header (ttl = 60.min) 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl =
4 /header (ttl = 60.min) 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl =
4 /header (ttl = 60.min)
2
/recent (ttl = 10.min)
1
3
/mini_feed (ttl = 30.min)
/news (ttl = 60.min)
<html>
<esi:include src="/mini_feed” max-age="1800"/>
</html>
Mongrel Mongrel Mongrel ESI Server h t m l + e s i http://readers.livingsocial.com html
Mongrel Mongrel Mongrel
Mongrel
Mongrel
Mongrel
Mongrel Mongrel Mongrel ESI Server h t m l + e s i http://readers.livingsocial.com html 1.
Mongrel Mongrel Mongrel ESI Server h t m l + e s i http://readers.livingsocial.com html 1.
Mongrel Mongrel Mongrel ESI Server h t m l + e s i http://readers.livingsocial.com html 1.
ESI Server
ESI
Server
Mongrel Mongrel Mongrel ESI Server h t m l + e s i http://readers.livingsocial.com html 1.

html + esi

html

t m l + e s i http://readers.livingsocial.com html 1. http://readers.livingsocial.com 2. Page Template (if not
1. http://readers.livingsocial.com 2. Page Template (if not cached) 3. Retrieve Fragments (if not cached)
1. http://readers.livingsocial.com
2. Page Template (if not cached)
3. Retrieve Fragments (if not cached)
1. http://readers.livingsocial.com 40
1. http://readers.livingsocial.com
1. http://readers.livingsocial.com
1. http://readers.livingsocial.com 2. Page Template (if not cached) 41
1. http://readers.livingsocial.com 2. Page Template (if not cached)
1. http://readers.livingsocial.com
2. Page Template (if not cached)
4 /header (ttl = 60.min) 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl =
4 /header (ttl = 60.min) 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl =
4 /header (ttl = 60.min)
2
/recent (ttl = 10.min)
1
3
/mini_feed (ttl = 30.min)
/news (ttl = 60.min)
1. http://readers.livingsocial.com
2. Page Template (if not cached)
4 2 1 3 1. http://readers.livingsocial.com 2. Page Template (if not cached) 3. Retrieve Fragments
4 2 1 3 1. http://readers.livingsocial.com 2. Page Template (if not cached) 3. Retrieve Fragments
4
2
1
3
1. http://readers.livingsocial.com
2. Page Template (if not cached)
3. Retrieve Fragments (if not cached)
“Assembles” 1. http://readers.livingsocial.com 2. Page Template (if not cached) 3. Retrieve Fragments (if not
“Assembles” 1. http://readers.livingsocial.com 2. Page Template (if not cached) 3. Retrieve Fragments (if not
“Assembles”
1. http://readers.livingsocial.com
2. Page Template (if not cached)
3. Retrieve Fragments (if not cached)
4. Respond back to User
1. http://readers.livingsocial.com
1. http://readers.livingsocial.com
4 2 1 3 1. http://readers.livingsocial.com 2. Page Template (cached) 3. Retrieve Fragments (cached) 4.
4 2 1 3 1. http://readers.livingsocial.com 2. Page Template (cached) 3. Retrieve Fragments (cached) 4.
4
2
1
3
1.
http://readers.livingsocial.com
2. Page Template (cached)
3.
Retrieve Fragments (cached)
4. Respond back to User
4 2 1 3 1. http://readers.livingsocial.com (cached) 2. Page Template (cached) 3. Retrieve Fragments (3
4 2 1 3 1. http://readers.livingsocial.com (cached) 2. Page Template (cached) 3. Retrieve Fragments (3
4
2
1
3
1. http://readers.livingsocial.com (cached)
2. Page Template (cached)
3. Retrieve Fragments (3 is cached)
4. Respond back to User
So what! Memcache can do that! 48

So what! Memcache can do that!

ESI

ESI ESI: Personalized Full Page Caching ESI: Concurrency ESI: Slow/Broken Dependencies ESI: Application Sharding

ESI: Personalized Full Page Caching ESI: Concurrency ESI: Slow/Broken Dependencies ESI: Application Sharding ESI: Polyglot Assembly ESI: Inline Invalidation ESI: Cached New User Experience

ESI: Personalized Full Page Caching caches_page cache(“whole_page”) { } headers[“Cache-Control”] =

ESI: Personalized Full Page Caching

caches_page cache(“whole_page”) { } headers[“Cache-Control”] = “max-age:3600”

Full Page Caching caches_page cache(“whole_page”) { } headers[“Cache-Control”] = “max-age:3600” 50
Full Page Caching caches_page cache(“whole_page”) { } headers[“Cache-Control”] = “max-age:3600” 50
Full Page Caching caches_page cache(“whole_page”) { } headers[“Cache-Control”] = “max-age:3600” 50
Full Page Caching caches_page cache(“whole_page”) { } headers[“Cache-Control”] = “max-age:3600” 50
ESI: Concurrency def show @ feed = @ person .mini_feed @ current = @ person

ESI: Concurrency

def show @feed = @person.mini_feed @current = @person.currently_reading @news = Blog.recent_by_vertical(“readingsocial”) end

ESI: Concurrency def show @ feed = @ person .mini_feed # 1s @ current =

ESI: Concurrency

def show @feed = @person.mini_feed # 1s @current = @person.currently_reading # 1s @news = Blog.recent_by_vertical(“readingsocial”) # 1s end

3s

ESI: Concurrency def mini_feed #1s def currently_reading #1s def news #1s 3s -> 1s 53

ESI: Concurrency

def mini_feed #1s

def currently_reading #1s

def news #1s

3s -> 1s

ESI: Slow/Broken Dependencies def show @feed = @person.mini_feed @current = @person.currently_reading @news =

ESI: Slow/Broken Dependencies

def show @feed = @person.mini_feed @current = @person.currently_reading @news = Blog.recent_by_vertical(“reading”)
def show
@feed = @person.mini_feed
@current = @person.currently_reading
@news = Blog.recent_by_vertical(“reading”) #10s
end
ESI: Slow/Broken Dependencies < esi: include src= ”/mini_feed” max-age= ”600” /> 55

ESI: Slow/Broken Dependencies

<esi:include src=”/mini_feed”

max-age=”600”/>

ESI: Slow/Broken Dependencies < esi: try > < esi: attempt > <esi:include src=”/mini_feed”

ESI: Slow/Broken Dependencies

<esi:try> <esi:attempt> <esi:include src=”/mini_feed” max-age=”600” timeout=”1”/> </esi:attempt> <esi:except> <esi:include src=”/static/mini_feed.html”/> </esi:except> </esi:try>

ESI: Application Sharding “Federate as much as you can” “A rails process should only be

ESI: Application Sharding

ESI: Application Sharding “Federate as much as you can” “A rails process should only be doing

“Federate as much as you can” “A rails process should only be doing one controller”

ESI: Application Sharding /mini_feed 58

ESI: Application Sharding

ESI: Application Sharding /mini_feed 58
ESI: Application Sharding /mini_feed 58
ESI: Application Sharding /mini_feed 58

/mini_feed

ESI: Application Sharding /mini_feed 58
ESI: Polyglot Assembly /mini_feed Merb/Erlang 59

ESI: Polyglot Assembly

ESI: Polyglot Assembly /mini_feed Merb/Erlang 59
ESI: Polyglot Assembly /mini_feed Merb/Erlang 59
ESI: Polyglot Assembly /mini_feed Merb/Erlang 59

/mini_feed

Merb/Erlang
Merb/Erlang
ESI: Cached New User Experience 4 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl
ESI: Cached New User Experience 4 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl
ESI: Cached New User Experience
4
2
/recent (ttl =
10.min)
1
3
/mini_feed (ttl = 30.min)
/news (ttl =
60.min)
ESI: Cached New User Experience 4 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl
ESI: Cached New User Experience 4 2 /recent (ttl = 10.min) 1 3 /mini_feed (ttl
ESI: Cached New User Experience
4
2
/recent (ttl =
10.min)
1
3
/mini_feed (ttl = 30.min)
/news (ttl =
60.min)
”/mini_feed?uid=$HTTP_COOKIE[
“uid”]”
ESI:Cached New User Experience 4 2 /recent (ttl = 1 3 /mini_feed (ttl = 30.min)
ESI:Cached New User Experience 4 2 /recent (ttl = 1 3 /mini_feed (ttl = 30.min)
ESI:Cached New User Experience
4
2
/recent (ttl =
1
3
/mini_feed (ttl = 30.min)
/news (ttl =
60.min)
”/mini_feed?uid=” Full Cache Hit!
ESI: Inline Invalidation <esi:invalidate> <basicselector uri= "/foo/bar/baz" />

ESI: Inline Invalidation

<esi:invalidate>

<basicselector uri="/foo/bar/baz"/>

<advancedselector uriexp="/ people/123/.* "/> </esi:invalidate>

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what?

- Edge Caching - FragmentFu

- Deployment Options

- Pros/Cons of Edge Caching

FragmentFu Project: google: FragmentFu “Proof of Concept” 65

FragmentFu

Project: google: FragmentFu “Proof of Concept”
Project:
google: FragmentFu
“Proof of Concept”
FragmentFu <%= render :esi => fragment_person_path, :ttl => 60.minutes %> 66

FragmentFu

<%= render :esi => fragment_person_path, :ttl => 60.minutes %>

FragmentFu def update invalidate_and_redirect_to (person_path(@person)) end 67

FragmentFu

def update

invalidate_and_redirect_to(person_path(@person))

end

FragmentFu def latest respond_to |wants| do wants. html { wants. js { end end }

FragmentFu

def latest

respond_to |wants| do

wants.html { wants.js { end end

}

}

#X-Requested-With = 'XMLHttpRequest'

FragmentFu def latest respond_to |wants| do wants. html { wants. js { } } wants.

FragmentFu

def latest

respond_to |wants| do

wants.html { wants.js {

}

}

wants.fragment { end end

#X-Requested-With = 'XMLHttpRequest' #X-Requested-With = ʻ ESIRequest'

}

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what?

- Edge Caching

- FragmentFu - Deployment Options

- Pros/Cons of Edge Caching

- Open Source - Commerical - Content Delivery Network 71
- Open Source - Commerical - Content Delivery Network 71

- Open Source

- Commerical

- Content Delivery Network

mongrel-esi

http://code.google.com/p/mongrel-esi/

- Small, but fast

- Open Source by Todd Fisher

- Ragel based parser

- memcache-backed caching

- Small, but fast - Open Source by Todd Fisher - Ragel based parser - memcache-backed
- Small, but fast - Open Source by Todd Fisher - Ragel based parser - memcache-backed
Squid http://www.squid-cache.org/ - In 2002, Zope funded ESI - Version 3.0+ - subset of ESI

Squid

Squid http://www.squid-cache.org/ - In 2002, Zope funded ESI - Version 3.0+ - subset of ESI support

http://www.squid-cache.org/

- In 2002, Zope funded ESI - Version 3.0+ - subset of ESI support

Varnish http://varnish.projects.linpro.no / - Supposedly Fast “ Squid is rather old and designed like computer

Varnish

Varnish http://varnish.projects.linpro.no / - Supposedly Fast “ Squid is rather old and designed like computer programs

- Supposedly Fast

Squid is rather old and designed

like computer programs where supposed

to be designed in 1980.”

- Varnish FAQ

- basic ESI support

- FunnyOrDie.com uses

Varnish http://www.funnyordie.com / - Supposedly Fast “Squid is rather old and designed like computer programs

Varnish

Varnish http://www.funnyordie.com / - Supposedly Fast “Squid is rather old and designed like computer programs where
- Supposedly Fast “Squid is rather old and designed like computer programs where supposed to
- Supposedly Fast
“Squid is rather old and designed like computer programs
where supposed to be designed in 1980.”
http://varnish.projects.linpro.no/wiki/FAQ
- subset of ESI support
- FunnyOrDie.com uses

56.6M views

Web Cache 10g BIG-IP WebAccelerator 76
Web Cache 10g BIG-IP WebAccelerator 76

Web Cache 10g

Web Cache 10g BIG-IP WebAccelerator 76

BIG-IP WebAccelerator

Web Cache 10g BIG-IP WebAccelerator 76
Web Cache 10g BIG-IP WebAccelerator 76
Web Cache 10g 2007 InfoQ Article - RevolutionHealth.com http://www.infoq.com/news/2007/02/revolution-health-profile

Web Cache 10g

2007 InfoQ Article - RevolutionHealth.com

http://www.infoq.com/news/2007/02/revolution-health-profile

“NetCraft says you've got Oracle Application Server 10g as the final “

public facing piece

“NetCraft says you've got Oracle Application Server 10g as the final “ public facing piece 77
“NetCraft says you've got Oracle Application Server 10g as the final “ public facing piece 77
Akamai Most Complete ESI Implementation 78
Akamai Most Complete ESI Implementation 78

Akamai

Akamai Most Complete ESI Implementation 78

Most Complete ESI Implementation

Agenda

Agenda - Examine a Rails Application - Apply Standard Caching Techniques - When thats not enough,

- Examine a Rails Application

- Apply Standard Caching Techniques

- When thats not enough, then what?

- Edge Caching

- FragmentFu

- Deployment Options - Pros/Cons of Edge Caching

Edge Caching - Cons YAGNI 80

Edge Caching - Cons

YAGNI

Edge Caching - Cons complexity 81

Edge Caching - Cons

Edge Caching - Cons complexity 81

complexity

Edge Caching - Cons cache invalidation 82

Edge Caching - Cons

cache

invalidation

Edge Caching - Cons cache invalidation 82
Edge Caching - Cons “ There are only two hard things in Computer Science: cache

Edge Caching - Cons

There are only two hard things in

Computer Science: cache invalidation

and naming things”

- Phil Karlton

Edge Caching - Cons lack of mature open source 84

Edge Caching - Cons

Edge Caching - Cons lack of mature open source 84

lack of mature open source

Edge Caching - Cons cost of deployment 85

Edge Caching - Cons

Edge Caching - Cons cost of deployment 85

cost of deployment

Edge Caching - Pros concurrent execution 86

Edge Caching - Pros

concurrent execution

Edge Caching - Pros concurrent execution 86
Edge Caching - Pros efficient execution 87

Edge Caching - Pros

Edge Caching - Pros efficient execution 87

efficient

execution

Edge Caching - Pros A/B Testing 88

Edge Caching - Pros

A/B

Testing

Edge Caching - Pros A/B Testing 88
Edge Caching - Pros def mini_feed def currently_reading def news RESTful application assembly 89

Edge Caching - Pros

def mini_feed

def currently_reading

def news

RESTful

application

assembly

Edge Caching - Pros Syndication for Free 90

Edge Caching - Pros

Syndication

for

Free

Edge Caching - Pros Syndication for Free 90
Edge Caching - Pros Geographically Distributed Personalization 91

Edge Caching - Pros

Edge Caching - Pros Geographically Distributed Personalization 91

Geographically

Distributed

Personalization

92
92

Q&A

Q&A 94