Sharedance, Memcached and Cache_Lite

Treasure ChestWith 125 million page impressions a month and highly dynamic content, caching is essential for tilllate.com. At tilllate, we have worked with several different caching techniques. Before we used caching, we just pre-generated the data: A nightly cron job populates a database table or generates a file containing the expensive data. Usually expensive queries, like the Most viewed pictures.

Then we are using Cache_Lite a lot. For example our homepage: If you look at the source code of our homepage you will notice the string <!--cache id a:4:{i:0;s:1:-->. This means that the page is coming out of the cache. There are a few disadvantages of Cache_Lite:

  • Before caching, you have to create the directories where the data is being stored in.
  • you have to take care of purging the old data.
  • If you want to use it in cluster environment and you dont want a copy of your homepage-markup (see example above) on every cluster member, you need to store it on NFS. And NFS and apache are enemies: If your NFS server hangs your web server will be stuck in uninterruptible sleep.

Party with Sharedance

Other caching tools we’re using are sharedance for user sessions or our own home-cooked solution storing data in shared memory via the shm_* functions of PHP.

However, our current way of dealing with cache is memcached, a “high-performance, distributed memory object caching system”. It is lightweight, fast, is made for use in a cluster environment, has good PHP support with a nice OO API, the Memcache class.

When you look at the photo galleries the queries to fetch the pictures from the database is being cached with memcache. The API is based on the mysql_* family of function. So getting used to it is easy:

[source:php]
$o=new MemcacheQuery(‘SELECT * FROM users ORDER BY username LIMIT 100’,600); // 600-seconds cache lifetime

while($row=$o->fetchAssoc())
{
echo “Username: “.$row[‘username’];
}
[/source]

The way we are using it for our photogalleries we get a 50-fold speed improvement when we have a cache hit. And the database server is not being stressed.

Don’t cache blindly

However, just replacing blindly all queries by a memcached version is not advisable.

  • In our use case we’re having a local database slave on every web server. So normal database access goes through a lightning-speed socket connection while memcache is always using a TCP connection.
  • The current implementation stores the whole resultset of the query in the cache. So in the case above it would be 100 rows. Even if just one row is needed the whole resultset will go through the network.
  • MySQL has a great query cache. As long as the data in the tables you’re using is not being changed often, this query cache is much faster than memcache.

It is probably a very developer-friendly way to use memcache, but certainly not the most efficient one.

However, if you take into account the overhead of caching and you use it on expensive data which changes seldomly, is accessed often you will save a huge amount of ressources when using memcache.

This entry was posted in PHP, Programming, Web Development. Bookmark the permalink.

Comments are closed.