Vcoderz Community
We create websites that have it all, beauty & brains
Lebanon Web Design & Development - Coddict
 

Go Back   Vcoderz Community > Computer Zone > Computers & Information Technologies

Notices

Computers & Information Technologies « Everything related to computers and internet. »

Reply
 
Share Thread Tools Search this Thread
Old 10-28-2009   #1
xcoder
Ma ghayro
 
xcoder's Avatar
 
Last Online: 04-19-2018
Join Date: Dec 2005
Posts: 5,592
Thanks: 1,765
Thanked 4,201 Times in 2,361 Posts
Groans: 12
Groaned at 18 Times in 11 Posts
Default PHP caching system - optimization idea

I was thinking about an effective caching system to reduce server load and DB connections and eventually makes the server traffic bandwidth bigger + faster response. I will be using an easy way to explain my idea.

Such system can be applied only on heavy traffic websites that have hundreds and thousands of page views every minute and same output to all clients not personalized or dynamic.
Blogs and news websites are the most to benefit from such system.

We will make easy calculations to compare before & after and how much this could reduce the load on the server and increase its traffic bandwidth and eventually servers that could cost thousands of dollars.

We will be using PHP script + MySQL + Apache

-------------------------

Before:

Pageviews: 100/minute
Average DB queries / page: 5

--------------------------------
DB queries on 100 visit: 5 x 100 = 500


How does the system work:

The system functionality is very simple, its main functionality is to create static pages (html) that were already compiled and don't require any PHP rendering nor SQL connections anymore, now every time a client request a page the HTML page will load.

Okay that's great but what if i needed to edit or delete a page... and applying this system on all my website plug ins could take ages to finish.

I already thought about this and the system is global, in a meaning it will cache the whole page (from top to bottom) and not part of it so you don't have to make it internal but global and add it to your page headers.
Editing the pages is very easy also you will understand it below:

Steps:
  1. Client-1 request a page
  2. System creates static copy of that page store it then load it to the client.
  3. Client-2 request a page
  4. The system checks the life_date of the static page, if it's < than 1 minute load it else go to step 2
So if any changes are made, it doesn't take longer than a minute to display. Of course you are free to set the time you wish and customize the system according to your needs in a way it caches parts of the website and not everything (hint: URL based)

After:
Pageviews: 100/minute
Average DB queries / page: 5
--------------------------------
So all SQL queries in 1 minute are simply 5

SQL connections reduced by 100 times, PHP rendering by almost 50% (since we are still loading the caching system on each request) and the response time has greatly increased especially on peak times.
The response time has greatly increased since the system has nothing to compile anymore.

This can seriously speed up your website like hell + reduce expenses + increase traffic bandwidth.

Of course it's not as simple as that and lot of things should be taken into consideration but this is the base idea of the system.
This is one of the things I'd like to develop.

=)


__________________
http://twitter.com/danymoussa
xcoder is offline   Reply With Quote
The Following User Says Thank You to xcoder For This Useful Post:
hegma (10-29-2009)
Old 10-28-2009   #2
Google

 
Google's Avatar
 
Last Online: 05-30-2013
Join Date: Jan 2008
Posts: 1,788
Thanks: 10,018
Thanked 1,100 Times in 651 Posts
Groans: 1
Groaned at 6 Times in 6 Posts
Default

[mouse]
Interesting idea. Already proposed many times, but not ideal.
I will post a detailed analysis as soon as I get a keyboard.

[/mouse]
__________________

Google is offline   Reply With Quote
Old 10-29-2009   #3
hegma
Registered Member
 
hegma's Avatar
 
Last Online: 10-02-2012
Join Date: Mar 2006
Posts: 366
Thanks: 110
Thanked 227 Times in 126 Posts
Groans: 12
Groaned at 14 Times in 8 Posts
Default

this photo explian the caching with php


As you can see, the MySQL database and Templates aren't touched, the web server just sends back the contents of a plain .html file to the browser. The request is completed in a fraction of the time, the user gets their page faster, and your server has less load on it...
Everyone's Happy.
__________________
Let's paint the world ORANGE

Last edited by hegma; 10-29-2009 at 10:34 AM.
hegma is offline   Reply With Quote
The Following User Says Thank You to hegma For This Useful Post:
xcoder (10-29-2009)
Old 01-26-2010   #4
xcoder
Ma ghayro
 
xcoder's Avatar
 
Last Online: 04-19-2018
Join Date: Dec 2005
Posts: 5,592
Thanks: 1,765
Thanked 4,201 Times in 2,361 Posts
Groans: 12
Groaned at 18 Times in 11 Posts
Default

I created the caching system last night and currently in use online and its' working very smoothly.

Find the codes below:

http://www.copypastecode.com/20949/
Code:
 class cache{
    
    // Attributes
    private $cache_dir;                                    // Cache directory (Default: document_root + cache/)
    private $expiry = 60;                                // Cache file life time in seconds
    private $min_file_size = 1024;             // Min file size in cache in bytes
    private $file_path;                                    // Page path / URL (Default: curent path)
    
    // Getters and setters
    public function setCacheDir($value)            {    $this->cache_dir = $value;            }
    public function setExpiry($value)                {    $this->expiry = $value;                    }
    public function setMinFileSize($value)    {    $this->min_file_size = $value;    }
    public function setFilePath($value)            {    $this->file_path = $value;            }
    
    public function getCacheDir()                        {    return $this->cache_dir;                }
    public function getExpiry()                            {    return $this->expiry;                        }
    public function getMinFileSize()                {    return $this->min_file_size;        }
    public function getFilePath()                        {    return $this->file_path;                }
    
    // To be executed on object creation
    public function __construct(){
        // Set default cache_dir path and File path
        $this->setCacheDir($_SERVER['DOCUMENT_ROOT'] . "/cache/");
        $this->setFilePath(self::currentPath());
    }
    
    // Load file / Page into string
    static function loadFileContent($file_path){
        $file_content = file_get_contents($file_path);
        return $file_content;
    }
    
    // Encryption used to decode pathes before storing them 
    private static function encrypt($str){
        return md5($str);
    }
    
    // Method to create cache file and store it
    public function createCacheFile(){
        
        // Make sure the required attributes are defined
        if($this->getCacheDir() and $this->getFilePath()){
        
            // Gets current page output
            $file_content = ob_get_contents();
            
            // Adds when the file was cached to the page bottom
            $file_content .= "";
            
            // Encrypt file path
            $file_path = $this->getCacheDir() . self::encrypt($this->getFilePath());
            
            // Create caching file
            $file_handle = fopen($file_path, 'w') or die("can't open file");
            fwrite($file_handle,$file_content);
            fclose($file_handle);
        
        // Throw an exception if the required parameters aren't defined
        }else{
            
            throw new Exception(__CLASS__ . ": Please define cache_dir and file_path to continue");
            
        }
        
    }
    
    // Method to load cached files
    public function loadFromCache(){
        
        // Make sure all required attributes are defined
        if($this->getCacheDir() and $this->getExpiry() and $this->getMinFileSize() and $this->getFilePath()){
            
            $file_path = $this->getCacheDir() . self::encrypt($this->getFilePath());
            
            // If file exists gather its information (done alone to reduce memory and CPU load on file info gathering)
            if(file_exists($file_path)){
            
                // Gather file information
                $file_age = time() - filemtime($file_path);
                $file_size = filesize($file_path);
                
                // If file exists and life expiry has not been reached yet and minimum file is above the minimum then include the file
                if($file_age < $this->getExpiry() and  $file_size > $this->getMinFileSize()){
                    include($file_path);
                    exit;
                }
                
            }
        
        // Throw an error if the required attributes weren't defined
        }else{
        
            throw new Exception(__CLASS__ . ": Please define cache_dir, expiry, file_path and min_file_size to continue");
        
        }
    }
        
    // Returns full current page path
    static function currentPath() {
         $pageURL = 'http';
         if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
         $pageURL .= "://";
         if ($_SERVER["SERVER_PORT"] != "80") {
            $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
         } else {
            $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
         }
         return $pageURL;
    }
    
    // Easy-to-implement load from cache
    public static function load($expiry = null, $min_file_size = null, $file_path = null, $cache_dir = null){
        
        // Try catch errors returned from object
        try{
        
            // Create object
            $obj = __CLASS__;
            $load_cache = new $obj;
            
            // Set attributes
            if($expiry !== null)                         $load_cache->setExpiry($expiry);
            if($min_file_size !== null)         $load_cache->setMinFileSize($min_file_size);
            if($file_path !== null)                    $load_cache->setFilePath($file_path);
            if($cache_dir !== null)                    $load_cache->setCacheDir($cache_dir);
            
            // Load from cache
            $load_cache->loadFromCache();
            
            // Destroy instance
            unset($load_cache);
        
        }catch(Exception $cache_errors){
            
            echo $cache_errors->getMessage();
            
        }
        
    }
    
    // Easy-to-implement write / create to cache
    public static function create($file_path = null, $cache_dir = null){

        // Try catch errors returned from object
        try{
        
            // Create object
            $obj = __CLASS__;
            $create_cache = new $obj;
            
            // Set attributes
            if($file_path !== null)        $create_cache->setFilePath($file_path);
            if($cache_dir !== null)        $create_cache->setCacheDir($cache_dir);
            
            // Create cache file
            $create_cache->createCacheFile();
            
            // Destroy instance
            unset($create_cache);
            
        }catch(Exception $cache_errors){
            
            echo $cache_errors->getMessage();
            
        }
        
    }

}
?>
It's very easy to implement:

Quote:
include('cache.class.php');
cache::create(); // Page top
cache::load(); // page bottom
Took me couple of hours to develop it and will consider extending it later or create a PHP based proxy server =)
__________________
http://twitter.com/danymoussa
xcoder is offline   Reply With Quote
Old 02-15-2010   #5
Google

 
Google's Avatar
 
Last Online: 05-30-2013
Join Date: Jan 2008
Posts: 1,788
Thanks: 10,018
Thanked 1,100 Times in 651 Posts
Groans: 1
Groaned at 6 Times in 6 Posts
Default

Cool script.
Other than that, use something lighter and faster than MD5.
MD5 will obviously slow down your script.

---

How about a PHP optimization competition?
I can prepare one if there will be enough participants.
The competition will involve a PHP script written in a bad way that must be optimized in order for it to run faster. So basically, we measure the time taken by each script to run and the person with the fastest script will be the winner.
__________________

Google is offline   Reply With Quote
Old 09-19-2010   #6
Sheriff Ice
info@sync.com.lb
 
Sheriff Ice's Avatar
 
Last Online: 11-29-2020
Join Date: Apr 2006
Posts: 3,827
Thanks: 1,348
Thanked 2,391 Times in 1,306 Posts
Groans: 0
Groaned at 16 Times in 15 Posts
Default

Great class im using it, its impressively amazing, reduced the load time dramatically
__________________
http://www.gamync.com Lebanese Produced Mobiles Games by http://www.sync.com.lb
Sheriff Ice is offline   Reply With Quote
Old 09-19-2010   #7
xcoder
Ma ghayro
 
xcoder's Avatar
 
Last Online: 04-19-2018
Join Date: Dec 2005
Posts: 5,592
Thanks: 1,765
Thanked 4,201 Times in 2,361 Posts
Groans: 12
Groaned at 18 Times in 11 Posts
Default

Quote:
Originally Posted by Google View Post
Cool script.
Other than that, use something lighter and faster than MD5.
MD5 will obviously slow down your script.

---

How about a PHP optimization competition?
I can prepare one if there will be enough participants.
The competition will involve a PHP script written in a bad way that must be optimized in order for it to run faster. So basically, we measure the time taken by each script to run and the person with the fastest script will be the winner.
Just saw your post, i am in as long it doesn't require much time from my side.
However, optimizing an application doesn't stop on the development level.
Apache could be tweaked to easily double and triple performance.

- Enable "Worker" mode instead of "Prefork" on apache.

- Enable Gzip or mod_deflate to compress output content even though this will increase CPU load but will reduce your page size dramatically and eventually make the page load way faster since it's compressed on the server side > sent to client > uncompressed by the client browser and displayed.

- Add PHP accelerator like APC along side with the PHP based caching system.

- Disable many options from PHP like "magic_quotes" for example.

- Use a PHP caching system and make sure it's the very first thing to load on the page, this will reduce PHP rendering to very low levels and totally stop any SQL connections. Refer to the first post in this thread.

Or simply go with advanced caching systems such as Memcached (More complicated than regular classes but does wonders, many popular websites such as twitter use it).

Tweaking your server and optimizing your application could make your machine handle times more traffic and serve your client at higher speed.
__________________
http://twitter.com/danymoussa
xcoder is offline   Reply With Quote
Old 09-19-2010   #8
xcoder
Ma ghayro
 
xcoder's Avatar
 
Last Online: 04-19-2018
Join Date: Dec 2005
Posts: 5,592
Thanks: 1,765
Thanked 4,201 Times in 2,361 Posts
Groans: 12
Groaned at 18 Times in 11 Posts
Default

Quote:
Originally Posted by Sheriff Ice View Post
Great class im using it, its impressively amazing, reduced the load time dramatically
Indeed, i'm using it on multiple websites and has been doing great so far.
However, this class is made for mass page caching and works great for news and blog websites, but it breaks when you have client interaction where results are supposed to be different for each client and an SQL caching system is required.

Therefore i thought about developing a more advanced class where it caches SQL results and pops them up if query encryption matches instead of placing an SQL request each time.

for example:

// Simple SQL query
Code:
select * from users where id = 32
// What the system actually does before running the query:
- Encrypt it, add client session or id to it "32541_00000ad589174863012860b04aae75cd" let's say and check if it exists in the cache. If it does just load it, if it doesn't:

Proceed with the SQL query, get the result > serialize it > cache it.

The difference in such caching system and the above is that leaving room for dynamic queries every minute have way more effect than the above system for a simple reason: Each client results of custom queries unlike a news website where a news-load query almost never changes.

Therefore the cache should be cleared upon modification (update,delete) only.

When the record is updated you simple clear the cache of 32541_*

Will post the class when developed.
__________________
http://twitter.com/danymoussa
xcoder is offline   Reply With Quote
Reply

  Vcoderz Community > Computer Zone > Computers & Information Technologies

Tags
caching, idea, optimization, php



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:09 AM.


Lebanon web design and development
Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Ad Management plugin by RedTyger
Share