Memcache: Rob Sharp Rob@sharp - Id.au Lead Developer The Sound Alliance
Memcache: Rob Sharp Rob@sharp - Id.au Lead Developer The Sound Alliance
Rob Sharp
rob@sharp.id.au
Lead Developer
The Sound Alliance
About Memcached
• 3 Linux servers
• Apache
• Lighttpd
• Memcache
• 1 MySQL Master
Why do we use
memcached?
• CMS written in OO style, using
Activerecord
• PHP4 and objects don't mix too well
• Activerecord gave us fast development but
reduced performance
• Call us greedy, but we want both
• Use Rails Memcache!
Our Application
• CMS written from the ground up
• Effectively three sites running on one
codebase
• Uses three seperate databases, but aiming
to consolidate more
• Has data namespacing implemented in most
places
• But seperation is not quite there yet!
Our Memcache Setup
require 'memcache'
memcache_options = {
:compression => true,
:debug => false,
:namespace => 'my_favourite_artists',
:readonly => false,
:urlencode => false
}
Cache.delete 'favourite_artist'
Memcache Namespaces
• Memcache doesn’t have namespaces, so we
have to improvise
• Prefix your keys with a namespace by
setting the namespace when you connect
• Our solution:
• Run multiple memcache instances on
different ports
Roll your own?
require 'cached_model'
memcache_options = {
:compression => true,
:debug => false,
:namespace => 'hifibuys',
:readonly => false,
:urlencode => false
}
end
cached_model
Performance
• CachedModel is not magic.
• CachedModel only accelerates simple finds for
single rows.
• CachedModel won’t cache every query you run.
• CachedModel isn’t smart enough to determine the
dependencies between your queries so that it can
accelerate more complicated queries. If you want
to cache more complicated queries you need do it
by hand.
Other options
• Joins Comments
• Joins ‘Rollcalls’
• Joins other secret developments
Our Example
• An article requires many data facets
• Most don’t change that often
• We also know when they change
• Yay for the Observer pattern
• User content changes much more
regularly
• Can be changed from outside our
controlled area (e.g. Forums)
Our Example
Summary
• Data can be loosely divided into editorially
controlled and user-generated
• Cache editorially controlled content
separately from user-generated content
• Simplest way to implement is in fragment
caching
Fragment Caching
• Memcache allows timed expiry of
fragments
• Identify areas that change infrequently and
cache
• Remember to measure performance before
and after
• Evidence suggests very large gains!
• Use memcache_fragments
Caching Fragments
rsharp$ sudo gem install memcache_fragments
require 'memcache_fragments'
memcache_options = {
:compression => true,
:debug => false,
:namespace => 'hifibuys',
:readonly => false,
:urlencode => false
}