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