Download pptx - Ror caching

Transcript
Page 1: Ror caching

Caching, in the web application world, is the art of taking a processed web page (or part of a webpage),

and storing it in a temporary location. If another user requests this same webpage, then we can serve up the

cached version.

Loading up a cached webpage can not only save us from having to do ANY database queries (i.e. no more rountd trips to server), it can even allow us to serve

up websites without touching our Ruby on Rails Server.

nd all this with lightning speed…

Caching!

Page 2: Ror caching

There's only one thing you'll need to do to start playing with caching.

Look for the following line and change it to true in your /config/environments/development.rb:

config.action_controller.perform_caching = true

NOTE: By default, caching is disabled for development and test, and enabled for production.

Configuration

Page 3: Ror caching

There are three types of caching techniques that Rails provides by default without the use of any third party plugins.

1) Page Caching2) Action Caching3) Fragment Caching

Type of caching

Page 4: Ror caching

Page caching is the FASTEST Rails caching mechanism, so you should do it if at all possible.

Where should you use page caching?If your page is the same for all users. If your page is available to the public, with no

authentication needed.

Page Caching

Page 5: Ror caching

It can’t be applied to every situation (such as pages that need authentication)

Since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.

Issues to be dealt with Page Caching

Page 6: Ror caching

Say we have a blog page (Imagine that!) that doesn't change very often. The controller code for our front page might look like this:

Page 7: Ror caching

As you can see, our List action queries the latest 10 blog posts, which we can then display on our webpage. If we wanted to use page caching to speed things up, we could go into our blog controller and do:

Page 8: Ror caching

The "caches_page" directive tells our application that next time the "list" action is requested, take the resulting html, and store it in a cached file.

Subsequent requests to the same url will now hit this html file rather then reloading the page. As you can imagine, loading a static html page is much faster than loading and processing a interpreted programming language.

Like 100 times faster!

Page 9: Ror caching

However, it is very important to note that Loading Page Cached .html files does not invoke Rails at all! What this means is that if there is any content that is dynamic from user to user on the page, or the page is secure in some fashion, then you can't use page caching. Rather you'd probably want to use action or fragment caching,

Page 10: Ror caching

So, how do you enable this super-fast cache behavior? Suppose you have a controller called ProductsController and an index action that lists all the products. You could enable caching for this action like this:

class ProductsController < ActionController caches_page :index def index; end

end

Example

Page 11: Ror caching

The first time anyone requests products/index, Rails will generate a file called index.html. If a web server see this file, it will be served in response to the next request for products/index, without your Rails application being called.

Page 12: Ror caching

By the way …

Where all these cached pages get stored ???

Page 13: Ror caching

By default, the page cache directory is set to Rails.public_path (which is usually set to File.join(self.root, "public") – that is, the public directory under your Rails application’s root).

The page caching mechanism will automatically add a .html extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages.

Page 14: Ror caching

What if we then say in our model:caches_page :show Where do you think the

cached page would get stored when we visited "/blog/show/5" to show a specific blog post?

The answer is /public/blog/show/5.htmlHere are a few more examples of where page

caches are stored.:

Page 15: Ror caching

Hey, wait a minute, notice how above the first item is the same as the last item. Yup, page caching is going to ignore all additional parameters on your url.

Page 16: Ror caching

Very interesting question, and a more interesting answer. In order to cache your different pages, you just have to create a differently formed url. So instead of linking "/blog/list?page=2", which wouldn't work because caching ignores additional parameters, we would want to link using "/blog/list/2", but instead of 2 being stored in params[:id], we want that 2 on the end to be params[:page].

We can make this configuration change in our /config/routes.rb

But what if I want to cache my pagination pages?

Page 17: Ror caching

the resulting url will be "/blog/list/2". When we click this link two great things will happen:

Rather than storing the 2 in params[:id], which is the default, the application will store the 2 as params[:page],

The page will be cached as /public/blog/list/2.html The moral of the story is; If you're going to use

page caching, make sure all the parameters you require are part of the URL, not after the question mark!

Page 18: Ror caching

In order to expire this page when a new product is added you could extend the products controller like this:

class ProductsController < ActionController caches_page :index def index; end

def create expire_page :action => :index end end

Page 19: Ror caching

action caching works like page caching except for the fact that the incoming web request does go from the web server to the Rails stack and Action Pack so that before filters can be run on it before the cache is served. This allows you to use authentication and other restrictions while still serving the result of the output from a cached copy.

Clearing the cache works in the exact same way as with page caching.

Action Caching

Page 20: Ror caching

Let’s say you only wanted authenticated users to edit or create a Product object, but still cache those pages:

Page 21: Ror caching

You can also use :if to pass a Proc that specifies when the action should be cached.

Also, you can use :layout => false to cache without layout so that dynamic information in the layout such as the name of the logged-in user or the number of items in the cart can be left uncached.

This feature is available as of Rails 2.2.

Page 22: Ror caching

Unfortunately, dynamic web applications usually build pages with a variety of components not all of which have the same caching characteristics.

In order to address such a dynamically created page where different parts of the page need to be cached and expired differently Rails provides a mechanism called Fragment Caching.

Fragment Caching

Page 23: Ror caching

Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in.

Page 24: Ror caching

As an example, if you wanted to show all the orders placed on your website in real time and didn’t want to cache that part of the page, but did want to cache the part of the page which lists all products available, you could use this piece of code:

Page 25: Ror caching
Page 26: Ror caching

Cache sweeping is a mechanism which allows you to get around having a ton of expire_{page,action,fragment} calls in your code.

It does this by moving all the work required to expire cached content into ActionController::Caching::Sweeper class.

This class is an Observer that looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.

Sweepers

Page 27: Ror caching
Page 28: Ror caching

Query caching is a Rails feature that caches the result set returned by each query. If Rails encounters the same query again during the current request, it will used the cached result set as opposed to running the query against the database.

Query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action.

SQL Caching

Page 29: Ror caching

Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk.

Cache Stores

Page 30: Ror caching

1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores everything into memory in the same process.

MemoryStoreis not only able to store strings, but also arbitrary Ruby objects. MemoryStoreis not thread-safe. Use SynchronizedMemoryStore instead if you need thread-safety.

The default cache stores provided with Rails include:

Page 31: Ror caching

2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk. This is the default store and the default path for this store is: /tmp/cache.

Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If /tmp/cache does not exist, the default store becomes MemoryStore.

Page 32: Ror caching

3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared DRb process that all servers communicate with.

This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process.

Page 33: Ror caching

4) MemCached store: Works like DRbStore, but uses Danga’s MemCache instead. Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites.

Special features:Clustering and load balancing. One can specify multiple

memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online.

Time-based expiry support. See write and the :expires_in option.

Per-request in memory cache for all communication with the MemCache server(s).

Page 34: Ror caching
Page 35: Ror caching

Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn’t changed since the last request and can be safely pulled from the browser cache.

They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers to pass back and forth both a unique content identifier and the timestamp of when the content was last changed. If the browser makes a request where the content identifier (etag) or last modified since timestamp matches the server’s version then the server only needs to send back an empty response with a not modified status.

Conditional GET Support

Page 36: Ror caching

Along with the built-in mechanisms outlined above, a number of excellent plugins exist to help with finer grained control over caching.

These includes 1) Chris Wanstrath’s excellent cache_fu plugin

http://errtheblog.com/posts/57-kickin-ass-w-cachefu

2) Evan Weaver’s interlock pluginhttp://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/

Advanced Caching

Page 37: Ror caching

http://guides.rubyonrails.org/caching_with_rails.html

http://www.railsenvy.com/2007/2/28/rails-caching-tutorial

http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2

http://www.ibm.com/developerworks/web/library/wa-rails1/

References:

Page 38: Ror caching

Thank you …