The
CacheAddOn implements a simple, aggressive server side caching
strategy for TWiki pages. The speed-up is considerable.
Rationale
While the functionality and flexibility of TWiki is nice and useful, it
comes at a high price: TWiki
is slow. Especially if you make use of
the form system combined with dynamic searches, performance is too slow
for slick day-to-day operation, i.e. page response time is consistently
>
> 1 sec. This is pitiful, as the generated pages could make excellent
navigation pages.
Here are benchmark figures for TWiki Dec2001 on a
SunBlade100 with
few plug-ins installed (
DefaultPlugin TablePlugin
EditTablePlugin IncludeIndexPlugin InterwikiPlugin
PdfPlugin SpacedWikiWordPlugin SpreadSheetPlugin
TWikiDrawPlugin XpTrackerPlugin)
Test case |
Min[s] |
Avg[s] |
Max[s] |
URL path |
Hello-world = load+compile+init perl |
0.65 |
0.75 |
0.93 |
/twiki/benchmark?-h |
Short page |
1.51 |
2.03 |
3.10 |
/twiki/render/TWiki/BumpyWord |
Formatted search |
2.44 |
2.58 |
3.17 |
/twiki/render/TWiki/TWikiContributor |
Large index w/much RCS |
5.36 |
5.82 |
7.46 |
/twiki/render/TWiki/WebIndex |
Large page w/INCLUDEs |
6.91 |
7.21 |
8.37 |
/twiki/render/TWiki/TWikiDocumentation |
mod_perl could cut the first figure, (startup+compile overhead), to
zero;
SpeedyCGI to almost zero.
If I understand correctly, for TWiki you can only
subtract that gain
of 0.65s from the other figures. 4.7s instead of 5.3s for the TWiki
documentation index -- no big deal.
Given that viewing is far more frequent than editing, caching could
significantly improve the speed of navigation, especially for computed
overview pages. Changes in reports or linked to pages are far less
frequent; even if some details are not displayed properly, it's not a
big deal while you are clicking along to your actual target page.
Client-side caching has a problem: you cannot detect changes from edits.
You definitely don't want
that. Therefore, caching can happen only
at the server side, where we
do know, whether the topic itself changed
or not.
Disadvantages:
- Wiki links, mostly to missing topics, may be out-dated;
- TWiki search results are very likely to be out-dated
- Layout changes in templates are not reflected in cached pages
- Decide between ultra fast but clunky Unix-only ksh/bash implementation versus optional, cleaner, but slower Perl version
- Cache eats disk space
- WebStatistics for view cannot does not count actual views, but refreshes
- Pages skinned via preferences would mix with normal pages in the cache
Advantages:
- The CPU load from heavily used RSS feeds decreases significantly
- It is a lot faster:
Test case | Min[s] | Avg[s] | Max[s] | URL path |
Hello-world = load+compile+init perl | 0.63 | 0.68 | 0.98 | /twiki/benchmark?-h |
Short page | 0.05 | 0.06 | 0.08 | /twiki/view/TWiki/BumpyWord |
Formatted search | 0.05 | 0.06 | 0.12 | /twiki/view/TWiki/TWikiContributor |
Large index w/much RCS | 0.05 | 0.06 | 0.07 | /twiki/view/TWiki/WebIndex |
Large page w/INCLUDEs | 0.05 | 0.07 | 0.10 | /twiki/view/TWiki/TWikiDocumentation |
How it works
Amazingly simple; primitive, even:
- The 'cache' shell [or perl] script replaces the view script
- It passes the environment 1:1 to the actual view = render script, but:
- It inserts a tee into the pipeline from the render script to the web server
- The tee output is stored in the file system
- Next time it's called, it compares the TWiki data file modification time with that of the cached page
- If the data file hasn't been modified, send the cached page to the user
- Otherwise, run the actual view script as above
The (original) shell version is ultra-fast, but relies on external scripts
(cronjob, 'fresh') for refreshing and invalidating the cache.
The Perl version does it all in one script, works nicely on Windows and
offers an option to control the maximum age of the cached copies.
Semantic of -maxage=n option |
n > 0 |
maximum age of cached copy [hours] |
n = 0 |
any change within web will invalidate cached copy (the shell script fresh supports this option as well) |
n < 0 |
flush all cached variants of page |
Installation Instructions
- Unpack the zipfile in
/your/twiki
File | Description | Variant |
bin/benchmark | to actually measure the improvement | shell |
bin/cache.sh | the shell caching wrapper for view/render | shell |
bin/cache.pl | the perl caching wrapper for view/render | perl |
bin/fresh | shell force rendering a fresh page into the cache | shell |
lib/TWiki/UI/edit.cache.diff | patch for edit script | optional for both |
data/TWiki/CachePlugin.txt | this description | both |
- Create the the
/your/twiki/cache
directory, make sure everything below is writable for the web server, e.g.
chgrp www /your/twiki/cache; chmod g+rwX /your/twiki/cache
- To minimize misleading out-dated edit links, modify the
/your/twiki/lib/TWiki/UI/Edit.pm
script with the supplied patch; add the .pl
suffix if necessary
Shell version
This is recommended for Unix, when you need maximum performance and don't
need any tinkering. It has been made to work on Windows, but the Perl
route is easier and faster.
- Copy [or hardlink] your
bin/view
script to bin/render
- Customize the path variables in
/your/twiki/bin/cache.sh
- Test it:
- Load a page from a web to be cached;
- Replace
/view/
in the URL by /cache.sh/
-> you should see the page as normal
- Check the cache directory -> an entry like
%2fYourPage%3f
should be there
- Force your browser to reload the page -> feel the difference?
- If you trust the caching, remove
bin/view
and copy bin/cache.sh
onto it
- If you are using
bin/viewauth
link it to bin/render
(For example the EditTablePlugin relies on this!)
- Either use the patch viewtopicactionbuttons.pattern.tmpl.patch, or:
- Change
/your/twiki/templates/viewtopicactionbuttons.pattern.tmpl
to have a refresh function, e.g. next to the the "More" link:
%TMPL:P{"sep"}%%TMPL:P{"refresh"}%
- Change
/your/twiki/templates/viewtopicactionbuttons.pattern.tmpl
to define the refresh function, %TMPL:DEF{"refresh"}%<span class="patternButton"><a href='%SCRIPTURL{"fresh"}%/%WEB%/%TOPIC%' rel='nofollow' %MAKETEXT{"title='Refresh'>Refresh"}%</a></span>%TMPL:END%
- Install a cron job to remove old cache entries; e.g. everything older than 2 weeks:
find /your/twiki/cache/ -mtime +14 -type f -exec rm {} \;
Perl version
This is preferred for Windows or if you need more cache aging control
from your templates.
- Copy your
bin/view.pl
script to bin/render.pl
- Customize the path variables in
/your/twiki/bin/cache.pl
- Test it:
- Load a page from a web to be cached;
- Replace
/view.pl/
in the URL by /cache.pl/
-> you should see the page as normal
- Check the cache directory -> an entry like
%2fYourPage%3f
should be there
- Force your browser to reload the page -> feel the difference?
- If you trust the caching, remove
bin/view.pl
and copy bin/cache.pl
onto it
- Either use the patch viewtopicactionbuttons.pattern.tmpl.patch, or:
- Change
/your/twiki/templates/viewtopicactionbuttons.pattern.tmpl
to have a refresh function, e.g. next to the the "More" link:
%TMPL:P{"sep"}%%TMPL:P{"refresh"}%
- Change
/your/twiki/templates/viewtopicactionbuttons.pattern.tmpl
to define the refresh function, %TMPL:DEF{"refresh"}%<span class="patternButton"><a href='%SCRIPTURL{"fresh"}%/%WEB%/%TOPIC%' rel='nofollow' %MAKETEXT{"title='Refresh'>Refresh"}%</a></span>%TMPL:END%
Usage
By definition, you should not see any difference. If you suspect a page
is outdated, click refresh. (You may want to insert the %DATE%
variable into your template to show the last render date.)
- A useful string to insert in your template is
<small> [cached %GMTIME{"$month $day $year at $hour:$min:$sec"}% - <i>[[%SCRIPTURL%/fresh%SCRIPTSUFFIX%/%WEB%/%BASETOPIC% refresh]]</i>]</small>
- this makes it easy to see the date, and also provides a Refresh link (calling the fresh
script on the page). [ RichardDonkin 13 Nov 2002 ]
- [ RichardDonkin 13 Nov 2002 ]
Add-On Info
See also
--
CharlesHowes - 28 Jun 2007