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 197...
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 197...
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




          f...
Why Cache?
November 1990
November 1990


Web Population: 1
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
   ...
Gateway Cache
Alice                                                                     Backend




        GET /foo      ...
Gateway Cache
Alice                                                                                      Backend




     ...
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




 ...
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                       GE...
Gateway Cache
Carol   (60 seconds later)                                                     Backend




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




    ...
expires_in
class FooController < Application

 def show
  expires_in 60.seconds, :public => true
  @foo = Foo.find(params[:...
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
   ...
Gateway Cache
Alice                                                         Backend




        GET /foo                  ...
Gateway Cache
Alice                                                                   Backend




        GET /foo        ...
Gateway Cache
Bob                   Backend
Gateway Cache
Bob                                   Backend




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




                                GE...
Gateway Cache
Bob                                                           Backend




                                GE...
Gateway Cache
Bob                                                                   Backend




                          ...
Rails: fresh_when
class FooController  Application

 def show
  @foo = Foo.find(params[:id])
  fresh_when :etag = @foo,
  ...
Rails: stale?
class FooController  Application

 def show
  @foo = Foo.find(params[:id])
  modified = @foo.updated_at.utc
...
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
   ...
Gateway Cache
Alice                                                                     Backend




        GET /foo      ...
Gateway Cache
Alice                                                                                      Backend




     ...
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




 ...
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




                           ...
Gateway Cache
Carol   (60 seconds later)                                                      Backend




                ...
Gateway Cache
Carol   (60 seconds later)                                                                   Backend




   ...
Never Generate The
Same Response Twice
use Rack::Cache
$ gem install rack-cache



config.middleware.use Rack::Cache,
 :verbose       = true,
 :metastore      = ...
High Performance
 Caches/Accelerators

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

• Varnish
 http://varnish.projects.linpro.no/
Heroku
Thanks!
HTTP's Best-Kept Secret: Caching
Upcoming SlideShare
Loading in...5
×

HTTP's Best-Kept Secret: Caching

22,820

Published on

Published in: Technology
1 Comment
41 Likes
Statistics
Notes
  • IT is a good PPT to explain web caching theory.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
22,820
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
499
Comments
1
Likes
41
Embeds 0
No embeds

No notes for slide




  • Pure ruby HTTP cache implementation.
    This talk is not really about Rack::Cache.
  • Heroku understands HTTP caching.
  • What we're talking about when we say HTTP caching.
    There's so many different caching systems.
  • Page caching, action caching, fragment caching, SQL caching, memcached.
  • *This* is what we're talking about
    Wire level
    Declarative.
    Don't worry if this doesn't look familiar.

  • All caches adhere to the same basic rules for the most part.
  • 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.
  • Many users behind a single cache


  • Also Known As &#x201C;Reverse Proxy Cache&#x201D;

  • The reasons have changed over time.

  • 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.
  • Explosive
    Netscape goes public in 1995

  • State of the art
    Roughly 2.3KB/s
    Today, yahoo.com homepage is 388K - 2m48s
  • Other things: CGI just starting out. (Guestbooks, hit counters, search)
    JavaScript - didn&#x2019;t exist.
    So what was the most important issue to solve?

  • Expires
    Last-Modified
  • Cache-Control
    ETag
  • Much more worried about load on backends.
    Do less work.



















  • I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • I use ETag and If-None-Match. Last-Modified and If-Modified-Since.
  • I use ETag and If-None-Match. Last-Modified and If-Modified-Since.


  • Halts












  • Requires Rails 2.3+ for Rack/middleware support.



  • HTTP's Best-Kept Secret: Caching

    1. 1. Caching HTTP’s Best Kept Secret
    2. 2. Ryan Tomayko http://tomayko.com/
    3. 3. Sinatra http://www.sinatrarb.com
    4. 4. Rack http://rack.rubyforge.org
    5. 5. Rack::Cache http://tomayko.com/src/rack-cache
    6. 6. Heroku http://heroku.com
    7. 7. HTTP Caching?
    8. 8. NOT Rails Caching
    9. 9. 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
    10. 10. 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
    11. 11. Types of Caches
    12. 12. Client Cache Client Client Client Cache Cache Cache foo.com
    13. 13. Shared Proxy Cache Shared Proxy Cache foo.com
    14. 14. Shared Proxy Cache Cache Cache foo.com
    15. 15. Shared Proxy Cache
    16. 16. Gateway Cache foo.com Gateway Cache Backend
    17. 17. Caches Everywhere Client Client Cache Cache Shared Cache foo.com Gateway Cache Backend
    18. 18. Why Cache?
    19. 19. November 1990
    20. 20. November 1990 Web Population: 1
    21. 21. February 1996 Web Population: 20M
    22. 22. February 1996 Modem Speed: 28.8kbps
    23. 23. February 1996
    24. 24. February 1996
    25. 25. Bandwidth.
    26. 26. February 1996 RFC 1945 - HTTP/1.0
    27. 27. March 1999 RFC 2616 - HTTP/1.1
    28. 28. Today
    29. 29. Expiration
    30. 30. Gateway Cache Alice Backend
    31. 31. Gateway Cache Alice Backend GET /foo Host: foo.com
    32. 32. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com
    33. 33. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com 200OK Cache-Control:public,max-age=60
    34. 34. 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
    35. 35. Gateway Cache Bob (30 seconds later) Backend
    36. 36. Gateway Cache Bob (30 seconds later) Backend GET /foo Host: foo.com
    37. 37. Gateway Cache Bob (30 seconds later) Backend GET /foo Host: foo.com 200OK Cache-Control:public,max-age=60 Age:30
    38. 38. Gateway Cache Carol (60 seconds later) Backend
    39. 39. Gateway Cache Carol (60 seconds later) Backend GET /foo Host: foo.com
    40. 40. Gateway Cache Carol (60 seconds later) Backend GET /foo GET /foo Host: foo.com Host: foo.com
    41. 41. Gateway Cache Carol (60 seconds later) Backend GET /foo GET /foo Host: foo.com Host: foo.com 200OK Cache-Control:public,max-age=60
    42. 42. 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
    43. 43. expires_in class FooController < Application def show expires_in 60.seconds, :public => true @foo = Foo.find(params[:id]) render :action => 'show' end end
    44. 44. Sinatra get '/foo' do headers['Cache-Control'] = 'public, max-age=60' @foo = Foo.find_and_stu erb :foo end
    45. 45. Validation (Conditional GET)
    46. 46. Gateway Cache Alice Backend
    47. 47. Gateway Cache Alice Backend GET /foo Host: foo.com
    48. 48. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com
    49. 49. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com 200OK ETag:quot;abcdef012345quot;
    50. 50. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com 200OK 200OK ETag:quot;abcdef012345quot; ETag:quot;abcdef012345quot;
    51. 51. Gateway Cache Bob Backend
    52. 52. Gateway Cache Bob Backend GET /foo Host: foo.com
    53. 53. Gateway Cache Bob Backend GET /foo GET /foo Host: foo.com Host: foo.com If-None-Match: abcdef012345
    54. 54. Gateway Cache Bob Backend GET /foo GET /foo Host: foo.com Host: foo.com If-None-Match: abcdef012345 304NotModified
    55. 55. Gateway Cache Bob Backend GET /foo GET /foo Host: foo.com Host: foo.com If-None-Match: abcdef012345 304NotModified 200OK ETag:abcdef012345
    56. 56. 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
    57. 57. 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
    58. 58. Sinatra: etag get '/foo' do @foo = Foo.find(params[:id]) etag @foo.etag erb :foo end
    59. 59. Expiration + Validation
    60. 60. Gateway Cache Alice Backend
    61. 61. Gateway Cache Alice Backend GET /foo Host: foo.com
    62. 62. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com
    63. 63. Gateway Cache Alice Backend GET /foo GET /foo Host: foo.com Host: foo.com 200OK Cache-Control:public,max-age=60 ETag:abcdef012345
    64. 64. 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
    65. 65. Gateway Cache Bob (30 seconds later) Backend
    66. 66. Gateway Cache Bob (30 seconds later) Backend GET /foo Host: foo.com
    67. 67. Gateway Cache Bob (30 seconds later) Backend GET /foo Host: foo.com 200OK Cache-Control:public,max-age=60 ETag:abcdef012345 Age:30
    68. 68. Gateway Cache Carol (60 seconds later) Backend
    69. 69. Gateway Cache Carol (60 seconds later) Backend GET /foo Host: foo.com
    70. 70. Gateway Cache Carol (60 seconds later) Backend GET /foo GET /foo Host: foo.com Host: foo.com If-None-Match: abcdef012345
    71. 71. 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
    72. 72. 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
    73. 73. Never Generate The Same Response Twice
    74. 74. 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
    75. 75. High Performance Caches/Accelerators •Squid http://www.squid-cache.org/ • Varnish http://varnish.projects.linpro.no/
    76. 76. Heroku
    77. 77. Thanks!
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×