Let me tell you a little story. My latest site I have been working on for some time was written using the Zend Framework. Since it was launched in Oct 07, it has been growing rapidly enough where I am now starting to feel growing pains.
One morning I went into the site to check some analytics, and my site was displaying a 403 Forbidden error! I suddenly got a cold nervous sweat down the back of my spine. Why was it forbidden? It was fine when I checked it out last night?! So I tried to login to my FTP account. No go! I I thought a hacker has some how blocked me out of my own account. [Exit dramatic build up].
I come to find out that my hosting company revoked my access to the folder that I was using for the domain. I called them up immediately after I noticed that. They responded by telling me that on a shared server, they limit their clients to use only 2% of the servers resources before they shut them down. My site was using 30%. They were then forced to shut the site down without notice, because it was most likely affecting the performance of the other sites running from that shared server.
After some negotiating and explaining to them that I was going to come up with a solution, they temporarily gave me back access to the folder so that I could diagnose further what was going on. The first thing that I did was looked through the server logs. Because of my unfortunate neglect, the server log file was freaking enormous bigger than normal.
Nearly all of the errors I was getting were:
[03-Jul-2008 09:41:19] PHP Fatal error: Uncaught exception 'Zend_Db_Adapter_Exception' with message 'SQLSTATE[42000] [1203] User blank already has more than 'max_user_connections' active connections' in blah blah blah
I’ll admit, I was in a huge hurry to get this project done, so I wasn’t thinking about the long tern effects. Needless to say, I wasn’t caching my MySQL query results. I know, tisk tisk. Once I discovered this, I added this private method to my classes:
private function loadCache()
{
$frontendOptions = array(
'lifetime' => 7200, // cache lifetime of 2 hours
'automatic_serialization' =>
true);
$backendOptions = array(
'cache_dir' => './cache/' // Directory where to put the cache files
); // getting a Zend_Cache_Core object
return Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
}
Then in each of my classes where I needed to cache my query results, I implemented the above method. Here is an example:
class IndexController extends Zend_Controller_Action {
/**
* Index Action
*
*/
public function indexAction() {
$db = new SomeDB;
$cache = $this->loadCache();
if (!$results = $cache->load('cache_variable')) {
$results = $db->fetchAll('columnName="whatIWant"');
$cache->save($results, 'cache_variable');
}
}
}
It’s pretty much as simple as that. Once I did this, it dropped the server load tremendously, which now buys me more time from upgrading my hosting package. About 10 minutes of coding just saved me about $50 a month in hosting fees! That feels good.
Keep in mind that this is not the best approach to solving this problem. If you too are using the Zend Framework in your own design. It was be better to initialize the Zend_Cache in your bootstrap file. Doing it the way I did above will force you to replicate the code method, loadCache, in all of your classes which I dont’ have to explain to you why this is inefficient, and just plain old bad OOP technique!

6 Comments until now
Thanks for sharing your experiences.
I’m also using Zend_Cache on my Web site
Zend_Cache is a great tool, especially when used with a very efficient backend like memchached or on a ramdisk. The best approach I have found is to use a controller plugin that has a preDispatchLoop or dispatchLoopStartup method, so you can still perform other necessary tasks through various other controller plugins like logging.
Here’s to the Zend Framework enjoying more and more attention!
Right now, as I am just testing it out with the site, I am using a File backend. I know that is not anywhere near efficient when placed against memcache. I should work on changing that here soon to give the site a little more of a performance boost.
You should consider caching entire pages, not just database queries. Would decrease your load even further.
That is a good idea. But for now, the only problem I was really having was too many mysql connections.
If I was to cache an entire page, using the Zend Framework, where would I do it? In the controller or view? I have no idea how I could implement a page cache in an MVC design pattern, lol. Please keep your laughing to a minimum.
Tweetbacks
Trackbacks
Add your Comment!