Memcache and Yii

Hi everyone,

I have just started to use Yii and find it really good. but there is one problem that i am facing is how should i implement Memcache. I have used memcache in the past and following is how i used to cache data.

User Management Scenario.

Find User by id

  • fetch from cache key e.g user-1

  • not find fetch from db set in cache.

Find All users

  • find all user ids from db.

  • loop through each id pass id into Find User by id method.

  • make and return array.

Now i am a bit confused how should i implement it in Yii Framework while using the awesome features that it provides by default. Any help will be appreciated.

Thanks.

Maybe you haven’t found the relevant section in the guide so here it is

Guide - Caching and API - CMemCache

During development you can simple simulate caching with API - CDummyCache e.g. if your dev environment doesn’t support caching.

Hey thanks for replying, i did read this section that’s how i came to know that Yii supports memcache by default.

However the examples given there suggest a different approach for caching result set. My approach is pretty straight forward as given in wikipedia.

In other words a single cache key for a single record not for all records which can/cannot be based on a certain criteria.

I can not get my approach to work with CActiveDataProvider. Any help?

I am interested in this topic as well. Unfortunately, I’m not exactly sure how to do it either…

One potential method: incorporate the memcache into the find/findAll methods directly. That is, the findByPk() will check memcache first before making a db call. I used this in another project (not Yii), and it worked pretty well.

But looking at the class reference now, I think it may better to go deeper. It seems like all of the ActiveRecord->find functions call ActiveRecord->query(), which in turn call ActiveRecord->populateRecords(). Have to look into it more.

I need to mention the one caveat to this method: the size of the ActiveRecord object is rather large. From a table with only 8 fields, the ActiveRecord object was about 40,000 characters, or 40kb. If you have a complicated table with 40 fields, you’ll be storing 200kb objects per record.

I was curious why you chose this algorithm. When we implemented our memcache before, we specifically decided not to do this because the one find all call could potentially turn into hundreds or thousands of single calls.

It basically boils down to type of data you are applying this algorithm to. Lets say if i have a list of countries to display then i would not use this algorithm, i’d rather cache whole countries result set. On the other hand if i have a blog i’d like to use this algorithm where the content is dynamic but it doesn’t change much. once in cache stays in cache unless someone flushes memcache.

If you want to cache a record from the database, you could override the default findByPk to something like:




public function findByPk(($id)

{

  if (<is record $id in cache>) {

    return unserialize(<data from cache>);

  }


  $record = parent::findByPk($id);

  store data in cache (serialized($record));


  return $record;

}



Remember that if you update the record, you must either update or delete the copy in cache.