ch05s06.html
8.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<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>