78 lines
8.1 KiB
HTML
78 lines
8.1 KiB
HTML
|
<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>
|