We recently installed memcached on a couple servers. As we begin to scale up our use of CakePHP, we quickly saw a need for some type of caching solution so that every page request wasn't running the full load of queries to render a page.

memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.


Jiri Kupiainen wrote a CakePHP / memcached component to help CakePHP developers utilize memcached. This in in addition to CakePHP's internal caching controller to move all CakePHP's built-in caching away from flat files and over to memcached. We have tuned up the vender/component that Jiri released and added some functionality.

The main issue with memcached is that is has only one namespace. This is fine for smaller projects or one or two developers, but when used in a large application, one namespace is just not acceptable. In addition to only having one namespace, there is no method for retreiving all the memcached keys that are in use. This means that unless you check to see if the key is in use everytime, and then validate the data from the key to determine that it is the data you need, not the data that someone else set, there is no way easy manage the keys and their data.

In the additions that we made to Jiri's files, we added a control key to memcache. This key holds an array of all the keys currently in use with memcached. This means that if you want to know what data is currently being stored by memcached, you can loop through the control array, and print out the data.

We implemented the storing of data in memcached for our new blog application going out next week. Every element on the page has a component that prepares the data for it. The controller loading all the components needed for a page simply specifies that caching will be used, and each component in turn checks if it's data has been cached. The cache is never flushed, until new data is added. We hooked into the afterSave method of our CakePHP models and have them check if the data being saved has any relation to any data stored in memcached, if it does, then we flush that key.

This allows for the developers to utilize memcached with little or no extra programming.

Download: cake_memcache vendor file, cake_memcache component file Controller: <?php class BlogEntryController extends AppController { var $uses = array('Blog'); var $helpers = array('Javascript','Session','NiceHead','Bookmark','CakeMemcache'); var $viewPath = 'blogs/entry'; var $caching = true; function view() { if(!$output = $this->CakeMemcache->use_cache($this,'holeId_' . $params['holeId'])) { // get list of blog entries // ------------------------ $this->Blog->unbindModel( array('hasMany' => array('BlogEntry')) ); $this->Blog->unbindModel( array('belongsTo' => array('BlogTheme')) ); $accounts = $this->Blog->find( array( 'Blog.id' => $params['blogId'] ), null, null, 1 ); $output['data'] = $accounts['Account']; unset($accounts); $this->CakeMemcache->set('holeId_' . $params['holeId'],$output); } $this->set('data' . $params['holeId'], $output); } ?> Each of our pages has "holes" assigned to it, each one of these holes contains an element with data given to it by it's matching component. We know which holes are associated with what blogs, so after saving any new data, we flush all the hole_## keys from memcached.
Views  1163 Comments  2
Filed under: CakePHP, memcached
Add Comment
Beth
Thanks for sharing. Cake 1.2 has memcache built in. I'm checking if cake has your server feature. If not, your mod's would be nice cake enhancement.
Chris
Beth, Yes CakePHP 1.2 has memcache included for core caching, but it doesn't have a good implementation for data caching, view caching, etc. This is why we use this component/vendor so that we can control multiple types of information that gets cached with memcache.
View Chris Thompson's profile on LinkedIn
Loading...