Wednesday, November 4, 2009

Cache in Rails (Intro)

Today i dedicate time to upgrade my rails application performance using cache techniques.

There a lot of solutions:
- Page caching
- Action Caching
- Fragment Caching
- Sweepers
- SQL Caching
- Advanced Caching

You can learn more here http://guides.rubyonrails.org/caching_with_rails.html.

If you have static pages that not change very often you can use Page caching.
Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver, without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can’t be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.


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.

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.

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

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.


Cache Money is a write-through and read-through caching library for ActiveRecord. Read-Through: Queries like User.find(:all, :conditions => ...) will first look in Memcached and then look in the database for the results of that query. If there is a cache miss, it will populate the cache. Write-Through: As objects are created, updated, and deleted, all of the caches are automatically kept up-to-date and coherent.



--More about the Cache Money -- Some of the Twitter solution --

Fist: Install and configure memcache.
http://www.danga.com/memcached/download.bml
tar zxvf memcache.tar.gz
./configure ( libevent is needed!)
make install
Lunch daemon /usr/local/bin/memcached -d -m 512 -l 127.0.0.1 -p 11211

Second: Install and configure cache-money gem
gem sources -a http://gems.github.com
sudo gem install nkallen-cache-money


Configure MemCached
More instructions in http://github.com/nkallen/cache-money.

Third: Use

Queries like User.find(1) will use the cache automatically. For more complex queries you must add indices on the attributes that you will query on. For example, a query like User.find(:all, :conditions => {:name => 'bob'}) will require an index like:

class User < ActiveRecord::Base
index :name
end

For queries on multiple attributes, combination indexes are necessary. For example, User.find(:all, :conditions => {:name => 'bob', :age => 26})

class User < ActiveRecord::Base
index [:name, :age]
end