Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Caching
HTTP’s Best Kept Secret
Ryan Tomayko
  http://tomayko.com/
Sinatra
http://www.sinatrarb.com
Rack
http://rack.rubyforge.org
Rack::Cache
http://tomayko.com/src/rack-cache
Heroku
http://heroku.com
HTTP Caching?
NOT Rails Caching
GET /foo HTTP/1.1
Host: www.foo.com
User-Agent: FooBrowser/1.0
Cache-Control: max-age=0
If-Modified-Since: Mon, 01 Jan 1979 ...
If-None-Match: abcdef0123456789
Accept: *



                   HTTP/1.1 200 OK
                   Content-Type: text/html
                   Content-Length: 24
                   Cache-Control: max-age=300
                   Last-Modified: Mon, 02 Jan 1979 ...
                   ETag: abcdef0123456789
                   Vary: Accept
GET /foo HTTP/1.1
Host: www.foo.com
User-Agent: FooBrowser/1.0
Cache-Control: max-age=0
If-Modified-Since: Mon, 01 Jan 1979 ...
If-None-Match: abcdef0123456789
Accept: *



                   HTTP/1.1 200 OK
                   Content-Type: text/html
                   Content-Length: 24
                   Cache-Control: public, max-age=300
                   Last-Modified: Mon, 02 Jan 1979 ...
                   ETag: abcdef0123456789
                   Vary: Accept
Types of Caches
Client Cache

Client    Client   Client
Cache     Cache    Cache




         foo.com
Shared Proxy Cache



      Shared Proxy
         Cache



       foo.com
Shared Proxy Cache

  Cache             Cache




          foo.com
Shared Proxy Cache
Gateway Cache



    foo.com
     Gateway
      Cache

     Backend
Caches Everywhere

 Client             Client
 Cache              Cache
           Shared
           Cache




          foo.com
          Gateway
           Cache

          Backend
Why Cache?
November 1990
November 1990


Web Population: 1
HTTP's Best-Kept Secret: Caching
February 1996


Web Population: 20M
February 1996


Modem Speed: 28.8kbps
February 1996
February 1996
Bandwidth.
February 1996


RFC 1945 - HTTP/1.0
March 1999


RFC 2616 - HTTP/1.1
Today
Expiration
Gateway Cache
Alice                   Backend
Gateway Cache
Alice                                   Backend




        GET /foo
        Host: foo.com
Gateway Cache
Alice                                             Backend




        GET /foo                  GET /foo
        Host: foo.com             Host: foo.com
Gateway Cache
Alice                                                                     Backend




        GET /foo                  GET /foo
        Host: foo.com             Host: foo.com




                                        200OK
                                        Cache-Control:public,max-age=60
Gateway Cache
Alice                                                                                      Backend




        GET /foo                                   GET /foo
        Host: foo.com                              Host: foo.com




                                                         200OK
            200OK
                                                         Cache-Control:public,max-age=60
            Cache-Control:public,max-age=60
Gateway Cache
Bob   (30 seconds later)                   Backend
Gateway Cache
Bob   (30 seconds later)                   Backend




      GET /foo
      Host: foo.com
Gateway Cache
Bob   (30 seconds later)                                Backend




      GET /foo
      Host: foo.com




           200OK
           Cache-Control:public,max-age=60
           Age:30
Gateway Cache
Carol   (60 seconds later)                   Backend
Gateway Cache
Carol   (60 seconds later)                   Backend




        GET /foo
        Host: foo.com
Gateway Cache
Carol   (60 seconds later)                             Backend




        GET /foo                       GET /foo
        Host: foo.com                  Host: foo.com
Gateway Cache
Carol   (60 seconds later)                                                     Backend




        GET /foo                       GET /foo
        Host: foo.com                  Host: foo.com




                                             200OK
                                             Cache-Control:public,max-age=60
Gateway Cache
Carol   (60 seconds later)                                                                  Backend




        GET /foo                                    GET /foo
        Host: foo.com                               Host: foo.com




                                                          200OK
             200OK
                                                          Cache-Control:public,max-age=60
             Cache-Control:public,max-age=60
expires_in
class FooController < Application

 def show
  expires_in 60.seconds, :public => true
  @foo = Foo.find(params[:id])
  render :action => 'show'
 end

end
Sinatra
get '/foo' do
 headers['Cache-Control'] =
              'public, max-age=60'
 @foo = Foo.find_and_stu
 erb :foo
end
Validation
 (Conditional GET)
Gateway Cache
Alice                   Backend
Gateway Cache
Alice                                   Backend




        GET /foo
        Host: foo.com
Gateway Cache
Alice                                             Backend




        GET /foo                  GET /foo
        Host: foo.com             Host: foo.com
Gateway Cache
Alice                                                         Backend




        GET /foo                  GET /foo
        Host: foo.com             Host: foo.com




                                        200OK
                                        ETag:quot;abcdef012345quot;
Gateway Cache
Alice                                                                   Backend




        GET /foo                            GET /foo
        Host: foo.com                       Host: foo.com




                                                  200OK
            200OK
                                                  ETag:quot;abcdef012345quot;
            ETag:quot;abcdef012345quot;
Gateway Cache
Bob                   Backend
Gateway Cache
Bob                                   Backend




      GET /foo
      Host: foo.com
Gateway Cache
Bob                                                           Backend




                                GET /foo
      GET /foo                  Host: foo.com
      Host: foo.com             If-None-Match: abcdef012345
Gateway Cache
Bob                                                           Backend




                                GET /foo
      GET /foo                  Host: foo.com
      Host: foo.com             If-None-Match: abcdef012345




                                      304NotModified
Gateway Cache
Bob                                                                   Backend




                                        GET /foo
      GET /foo                          Host: foo.com
      Host: foo.com                     If-None-Match: abcdef012345




                                              304NotModified
          200OK
          ETag:abcdef012345
Rails: fresh_when
class FooController  Application

 def show
  @foo = Foo.find(params[:id])
  fresh_when :etag = @foo,
    :last_modified = @foo.updated_at.utc
 end

end
Rails: stale?
class FooController  Application

 def show
  @foo = Foo.find(params[:id])
  modified = @foo.updated_at.utc
  if stale?(:etag = @foo, :last_modified = modified)
    respond_to do |wants|
     # ... normal response processing
    end
  end
 end

end
Sinatra: etag
get '/foo' do
 @foo = Foo.find(params[:id])
 etag @foo.etag

 erb :foo
end
Expiration
    +
Validation
Gateway Cache
Alice                   Backend
Gateway Cache
Alice                                   Backend




        GET /foo
        Host: foo.com
Gateway Cache
Alice                                             Backend




        GET /foo                  GET /foo
        Host: foo.com             Host: foo.com
Gateway Cache
Alice                                                                     Backend




        GET /foo                  GET /foo
        Host: foo.com             Host: foo.com




                                        200OK
                                        Cache-Control:public,max-age=60
                                        ETag:abcdef012345
Gateway Cache
Alice                                                                                      Backend




        GET /foo                                   GET /foo
        Host: foo.com                              Host: foo.com




             200OK                                       200OK
             Cache-Control:public,max-age=60             Cache-Control:public,max-age=60
             ETag:abcdef012345                           ETag:abcdef012345
Gateway Cache
Bob   (30 seconds later)                   Backend
Gateway Cache
Bob   (30 seconds later)                   Backend




      GET /foo
      Host: foo.com
Gateway Cache
Bob   (30 seconds later)                                Backend




      GET /foo
      Host: foo.com




            200OK
            Cache-Control:public,max-age=60
            ETag:abcdef012345
            Age:30
Gateway Cache
Carol   (60 seconds later)                   Backend
Gateway Cache
Carol   (60 seconds later)                   Backend




        GET /foo
        Host: foo.com
Gateway Cache
Carol   (60 seconds later)                                           Backend




                                       GET /foo
        GET /foo                       Host: foo.com
        Host: foo.com                  If-None-Match: abcdef012345
Gateway Cache
Carol   (60 seconds later)                                                      Backend




                                       GET /foo
        GET /foo                       Host: foo.com
        Host: foo.com                  If-None-Match: abcdef012345




                                              304NotModified
                                              Cache-Control:public,max-age=60
Gateway Cache
Carol   (60 seconds later)                                                                   Backend




                                                    GET /foo
        GET /foo                                    Host: foo.com
        Host: foo.com                               If-None-Match: abcdef012345




              200OK                                        304NotModified
              Cache-Control:public,max-age=60              Cache-Control:public,max-age=60
              ETag:abcdef012345
Never Generate The
Same Response Twice
use Rack::Cache
$ gem install rack-cache



config.middleware.use Rack::Cache,
 :verbose       = true,
 :metastore      = quot;file:/var/cache/rack/metaquot;,
 :entitystore = quot;file:/var/cache/rack/bodyquot;,
 :allow_reload = false,
 :allow_revalidate = false
High Performance
 Caches/Accelerators

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

• Varnish
 http://varnish.projects.linpro.no/
Heroku
Thanks!

More Related Content

HTTP's Best-Kept Secret: Caching

Editor's Notes

  • #6: Pure ruby HTTP cache implementation. This talk is not really about Rack::Cache.
  • #7: Heroku understands HTTP caching.
  • #8: What we're talking about when we say HTTP caching. There's so many different caching systems.
  • #9: Page caching, action caching, fragment caching, SQL caching, memcached.
  • #10: *This* is what we're talking about Wire level Declarative. Don't worry if this doesn't look familiar.
  • #12: All caches adhere to the same basic rules for the most part.
  • #13: Or browser cache. People are most familiar with. When we think about HTTP caching, this is what comes to mind. Bandwidth/Traffic Reduction. Number of Clients served by the Cache. I don&#x2019;t want to talk about Client caches.
  • #14: Many users behind a single cache
  • #17: Also Known As &#x201C;Reverse Proxy Cache&#x201D;
  • #19: The reasons have changed over time.
  • #21: First server, client/browser, and web page Things are good for, like, a year. Ramble about research guys trading papers and linking to each other.
  • #22: Explosive Netscape goes public in 1995
  • #23: State of the art Roughly 2.3KB/s Today, yahoo.com homepage is 388K - 2m48s
  • #24: Other things: CGI just starting out. (Guestbooks, hit counters, search) JavaScript - didn&#x2019;t exist. So what was the most important issue to solve?
  • #26: Expires Last-Modified
  • #27: Cache-Control ETag
  • #28: Much more worried about load on backends. Do less work.
  • #47: I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • #48: I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • #49: I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • #50: I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • #53: Halts
  • #66: Requires Rails 2.3+ for Rack/middleware support.