ch05s06.html 8.11 KB
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Efficient graph generation using the built-in cache subsystem</title><link rel="stylesheet" type="text/css" href="manual.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.0"><link rel="home" href="index.html" title="JpGraph Manual"><link rel="up" href="ch05.html" title="Chapter 5. Fundamentals of dynamic graph generation"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Efficient graph generation using the built-in cache subsystem</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center">Chapter 5. Fundamentals of dynamic graph generation</th><td width="20%" align="right"> </td></tr></table><hr></div><div class="sect1" title="Efficient graph generation using the built-in cache subsystem"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sec.efficient-graph-generation"></a>Efficient graph generation using the built-in cache subsystem</h2></div></div></div>
            
            <p>The full explanation of how to use the JpGraph cache system is deferred to <a class="xref" href="ch09.html" title="Chapter 9. Using the JpGraph cache system">Chapter 9. <i>Using the JpGraph cache system</i></a> so this early section is just to explain the
                principles and why you probably want to read through the full chapter later
                on.</p>
            <p>The core problem is that generating images can require a lot of CPU time. If we
                combine this with the interpreted nature of PHP we can get a potential lethal
                performance mixture. For example, if a web page uses one dynamically generated graph
                and at its peak the site has 50 hits per second this means that the PHP graph script
                also has to be called 50 times a second. On a high end server a typical graph takes
                in the range of 0.02s up to 0.2s (and some complex graph, for example an
                anti-aliased Contour-plot, can take up to 1s) to generate using a plain
                non-accelerated installation (see more on supported PHP Accelerators in <a class="xref" href="ch11.html" title="Chapter 11. NuSphere PHP accelerator">Chapter 11. <i>NuSphere PHP accelerator</i></a>).</p>
            <p>If we furthermore makes the realistic assumption that the site needs to run some
                database services and generate other content as well the graph script itself might
                not be allowed to use more than 50% of the available CPU bandwidth. It is now easy
                to see that we are in trouble.</p>
            <p>Continuing with the example. Assuming our graph is medium complex and takes a
                whole 0.04s to generate. This means that if the server does not do anything more
                than just creating images then we can crank out 1/0.04 or 25 graphs per second per
                core at maximum. If we then take the 50% load into account it means that we could
                only be allowed to generate ~12 graphs per second per core and remember that this
                was on a high end server. If we now have more than 12 hits per second or have a more
                average server with a less powerful CPU we are heading directly for a seriously
                under dimensioned server.</p>
            <p>If we assume we are running our server on a dual-core CPU this gives us an upper
                practical limit of 24 graphs per second per server.</p>
            <p>There are a couple of ways to counteract this problem but none is a 100%
                solution.</p>
            <div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
                        <p>Introduce load balancing among several servers. This is a common way
                            to dynamically adjust to varying loads but without some serious
                            investments into a server farm it is still possible to overload the
                            system.</p>
                    </li><li class="listitem">
                        <p>Reduce the complexity of the graphs. However there is still a limit,
                            even very simple and basic graphs takes in the order of 0.02s on a high
                            end server due partly to the cost PHP parsing of all the library files.
                            This means that the upper limit is still valid.</p>
                    </li><li class="listitem">
                        <p>Make use of a PHP accelerator. If you are running a professional
                            server this is a must. We would go so far as to say that running a
                            professional PHP server without using any of the available PHP
                            accelerators borders on gross misconduct on the behalf of the
                            information architect that did the logical server design. Using a PHP
                            accelerator we can normally expect to get an almost 100% improvement.
                            Taking the previous example as a case we can probably expect an upper
                            limit of ~24 graphs per second per core instead of the normal
                            ~12.</p>
                    </li><li class="listitem">
                        <p>Make use of the built in cache system in JpGraph. This system if set
                            up correctly will avoid the problem by not having to generate the same
                            (or almost the same) image over and over again. The core idea of the
                            system is the observation that the majority of the data presented on a
                            WEB page is changing only very slowly compared with the hits a server
                            gets. </p>
                        <p>For example, if a server has a graphical overview of defects by
                            showing inflow/outflow there is probably a good case to state that the
                            data change sufficiently slowly that it is probably not necessary to
                            re-generate the graph more than 6 times per day (or perhaps even just
                            once per day).</p>
                        <p>The JpGraph cache system allows you to do just that. What you do is
                            specify a timeout. When the server calls the graph script the script
                            first checks if a previous image has been generated. If that is the case
                            it then checks how old the image is and if it is newer than the timeout
                            limit then the existing image is sent back. It is just in the case that
                            there isn't already any image (the script has never been run) or that
                            the existing image is too old (older than the specified timeout limit)
                            that the image gets generated again.</p>
                        <p>You could of course do all of this manually but the library has built
                            in support for this that will allow you to use the system without
                            changing a single line in your existing scripts. It is all taken care of
                            in the background.</p>
                    </li></ol></div><p>For a production server the recommended setup is to use a combination
                of load balancing, a suitable PHP accelerator and enabling the JpGraph cache
                system.</p>
        </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"><a accesskey="u" href="ch05.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>