Reduce Server Load Of MyBB

March 5, 2014 06:50:41

Το MyBB is one of the best free platforms to create a forum. However, it has some problems with server resources.

With a simple search, you can find dozens of reports about increased memory consumption (and processor) on servers, especially on shared. My friend recently asked me to help him, because the company hosts his site blocked his access.

There are some solutions, such as this Guide (or this one), but when the forum has a lot of visits, MyBB again consumed too much memory, so another solution had to be found.

One problem with MyBB is how parses and displays the posts, and a solution is to use this plugin, where it actually caches the posts (and signatures) and display them from there.

Although these solutions that somewhat reduced resource consumption, yet there were problems with the server and I decided to look more closely at the issue. So I found that the problem was mainly caused by the attachment.php and showthread.php files, with the first one having the most consumption. Looking at the code, I noticed that it did a lot of queries in the database (for a single attachment), meaning that in posts with many pictures as attachments and in a post that had many visits, it does too many queries, which had to be reduced somehow.

So the only solution was to use a simple yet effective cache method, where it would help to reduce the queries. The solution is relatively simple and it works.

First create a new folder in the forum's "cache" folder and name it "thumbs" (without quotation marks). There upload a blank file named "index.html" to prevent the files from appearing, or block any access with a .htaccess file with the following:


Order Deny,Allow
Deny from all

Now open the "attachment.php" file with a text editor. In the beginning, insert these two functions, are to read/write the cache:


//Write Cache
function writeCache($data, $cacheFile){ 
if (!$fp = fopen($cacheFile, 'w')) {
trigger_error('Error opening cache file');
exit();
}
if (!flock($fp, LOCK_EX)) {
trigger_error('Unable to lock file');
exit();
}
if (!fwrite($fp, serialize($data))) {
trigger_error('Error writing to cache file');
exit();
}
flock($fp, LOCK_UN);
fclose($fp);
}

//Read Cache
function readCache($cacheFile) {
if (!file_exists($cacheFile)) {
trigger_error('Invalid cache file');
exit();
}
return unserialize(file_get_contents($cacheFile));
}

Now, from this line:

// Find the AID we're looking for
if($mybb->input['thumbnail'])

up to this:

// Get forum info
$forum = get_forum($fid);

delete everything and replace it with this code:


//Custom Mod Start
$hash = 'test123'; //Here write anything you want, is for security purposes
$expireTime = 86400; //24 h (any time you want)

// Find the AID we're looking for
if($mybb->input['thumbnail']) {
    $aid = intval($mybb->input['thumbnail']);
    $cacheFile = 'cache/thumbs/' . md5($hash.$aid) . '-thumbnail.php';
} else {
    $aid = intval($mybb->input['aid']);
    $cacheFile = 'cache/images/' . md5($hash.$aid) . '.php';
}

$plugins->run_hooks("attachment_start");
$pid = intval($mybb->input['pid']);

if( ($aid) && file_exists($cacheFile) && (filemtime($cacheFile) > (time() - $expireTime))) {
$cache_dt = readCache($cacheFile);
//Build Info
$attachment = $cache_dt['attachment'];
$pid = $attachment['pid'];
$post = $cache_dt['post'];
$thread = $cache_dt['thread'];

$fid = $thread['fid'];
$forum = $cache_dt['forum'];
//Free some memory
unset($cache_dt);
} else {
if($aid)    
$query = $db->simple_select("attachments", "*", "aid='{$aid}'");
else
$query = $db->simple_select("attachments", "*", "pid='{$pid}'");
$cache_dt = array();

$attachment = $db->fetch_array($query);
$pid = $attachment['pid'];
$post = get_post($pid);
$thread = get_thread($post['tid']);

if(!$thread['tid'] && !$mybb->input['thumbnail'])
error($lang->error_invalidthread);

$fid = $thread['fid'];

// Get forum info
$forum = get_forum($fid);

//Build Cache
$cache_dt['attachment'] = $attachment;
$cache_dt['post'] = $post;
$cache_dt['thread'] = $thread;
$cache_dt['forum'] = $forum;
$cache_dt['forumpermissions'] = $forumpermissions;

//Caching
writeCache($cache_dt, $cacheFile);
//Free some memory
unset($cache_dt);
}

That's it. Try and you will see a significant change in attachments' speed, especially if there are many photos in one post.

Something similar can be done in the file "showthread.php", but it is not so necessary, since a forum with many attachments causes server issues. You can also disallow the visitors viewing the thumbnails or even set the browser to cache images instead of asking them again from the server (it requires additional code in the "attachment.php" file or in .htaccess file). I hope the newer version of MyBB (2.0) to solve these problems.