Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
Caching | 119

# use the read-only connection
@user = ReadSlave::User.find(params[:id])

# write to the master (can't use @user.update_attributes because it would
# try to write to the read slave)
User.update(@user.id, :login => "new_login")

Caching


If you have far more reads than writes, model caching may help lighten the load on
the database server. The standard in-memory cache these days ismemcached.*Devel-
oped for LiveJournal, memcached is a distributed cache that functions as a giant
hashtable. Because of its simplicity, it is scalable and fast. It is designed never to
block, so there is no risk of deadlock. There are four simple operations on the cache,
each completing in constant time.


You can actually use memcached in several different places in Rails. It is available as
a session store or a fragment cache store out of the box, assuming the ruby-
memcache gem is installed. It can also be used to store complete models—but
remember that this will only be effective for applications where reads vastly outnum-
ber writes. There are two libraries that cover model caching: cached_model and
acts_as_cached.


The cached_model library (http://dev.robotcoop.com/Libraries/cached_model/index.
html) provides an abstract subclass ofActiveRecord::Base,CachedModel. It attempts
to be as transparent as possible, just caching the simple queries against single objects
and not trying to do anything fancy. It does have the disadvantage that all cached
models must inherit fromCachedModel. Use of cached_model is dead simple:


class Client < CachedModel
end

On the other hand, the acts_as_cached plugin (http://errtheblog.com/post/27) gives
you more specificity over what is cached. It feels more like programming against
memcached’s API, but there is more power and less verbosity. It has support for rela-
tionships between objects, and it can even version each key to invalidate old keys
during a schema change. A sample instance of acts_as_cached might look like this:


class Client < ActiveRecord::Base
acts_as_cached

# We have to expire the cache ourselves upon significant changes
after_save :expire_me
after_destroy :expire_me

protected


  • Pronounced “mem-cache-dee,” for “memory cache daemon.” Available fromhttp://danga.com/memcached/.

Free download pdf