Item11549: Rewrite of page cache, improved performance, better page dependency capture.
Priority: Enhancement
Current State: Closed
Released In: 2.0.0
Target Release: major
Applies To: Engine
Component: PageCache
Branches: Release01x01 trunk
Use DBI to capture the dependencies among wiki pages
have a BDB fallback for low-tech setups.
- make Foswiki::PageCache a virtual class
- implement Foswiki::PageCache::DBI
- test against mysql ... (works, but not covered by unit tests yet)
- test against sqlite ... (works, but not covered by unit tests yet)
- test against postgresql ... (works, but not covered by unit tests yet)
-
implement Foswiki::PageCache::BDB ... not worth it
- removal of all Foswiki::Cache classes
- adjust of Fosiwki.spec and configure checkers: only offer the caching settings when the perl classes are available actually.
- compare performance wrt speedup and throughput
- documentation
--
MichaelDaum - 22 Feb 2012
Awesome! Would love to try a mongo impl, for those who might already be running it
--
PaulHarvey - 22 Feb 2012
Benchmarking random topics from the System web using
siege.
Parameters:
- nr concurrent requrests = 10
- nr transactions = 8000
- dual core 3.16GHz, 4GB ram linux server
- lighttpd
- running over localhost loopback
Setup |
Elapsed time |
Data transferred |
Transaction rate |
Throughput |
Max response time |
Avg response time |
Min response time |
1 |
cgi |
4088.18 secs |
202.00 MB |
1.87 trans/sec |
0.05 MB/sec |
26.66 sec |
5.18 secs |
2.88 sec |
2 |
fcgi |
1768.69 secs |
217.20 MB |
4.33 trans/sec |
0.12 MB/sec |
28.63 sec |
2.09 secs |
0.28 sec |
3 |
cache, cold, cgi, sqlite |
4232.35 secs |
201.38 MB |
1.78 trans/sec |
0.05 MB/sec |
23.17 sec |
5.20 secs |
0.81 sec |
4 |
cache, warme, cgi, sqlite |
2748.95 secs |
238.79 MB |
2.79 trans/sec |
0.09 MB/sec |
15.11 sec |
3.58 secs |
0.67 sec |
5 |
cache, cold, fcgi, sqlite |
1220.26 secs |
233.27 MB |
6.30 trans/sec |
0.19 MB/sec |
29.96 sec |
1.54 secs |
0.15 sec |
6 |
cache, warm, fcgi, sqlite |
603.89 secs |
234.01 MB |
12.70 trans/sec |
0.39 MB/sec |
5.00 sec |
0.78 secs |
0.13 sec |
7 |
cache, cold, fcgi, mysql |
1058.39 secs |
227.42 MB |
7.27 trans/sec |
0.22 MB/sec |
18.28 sec |
1.32 secs |
0.27 sec |
8 |
cache, warm, fcgi, mysql |
596.37 secs |
237.74 MB |
12.86 trans/sec |
0.40 MB/sec |
3.96 sec |
0.77 secs |
0.13 sec |
9 |
cache, cold, fcgi, mysql, gzip |
1106.37 secs |
53.73 MB |
6.96 trans/sec |
0.05 (0.21) MB/sec |
20.21 sec |
1.40 secs |
0.14 sec |
10 |
cache, warm, fcgi, mysql, gzip |
572.22 secs |
55.29 MB |
13.40 trans/sec |
0.10 (0.42) MB/sec |
7.73 sec |
0.74 secs |
0.13 sec |
Legend:
- cgi: good old cgi
- fcgi: fast-cgi
- cache: page cache enabled
- cold: page cache cleared before testing
- warm: all pages served from cache
- sqlite: use sqlite to store meta information about cached pages
- mysql: use mysql to store meta information about cached pages
- gzip: use http compression, throughput valus in brackets show uncompressed net data comparable to uncompressed transfers
--
MichaelDaum - 23 Feb 2012
Impressive! For something to be useful on foswiki.org, can you think of any way an afterSaveHandler or log listener might be used to trigger the mirrored foswiki to invalidate a topic? We'd also need something like that for the topics maintained from cron - Task commits, etc.
--
GeorgeClark - 23 Feb 2012
Any
save
invalidates the page cache of this topic. So when would you require to implement a manual invalidation of some other topic?
When the cron scripts use the proper api to save changes, will the cache entry be invalidated automatically. Not so if the cron scripts tinker with the txt file only, not notifying the core about it. In that case you may invalidate the page cache for a topic using
cd <foswiki-root>/bin
./view topic=Some.Topic refresh=on
On foswiki.org, all content is also served by trunk.foswiki.org, presumably using soft-links on the filesystem to bring the same content to the other engine.
Imagine both engines use page caching. The problem now is that all changes only go through one of the engine while the other might still uses an outdated cache entry. In this case a solution might be to use the same database backend for both engines. This way they sort of share the same storage for the cache but have separate cache entries for the same topic as their domain differs. So when one engine detects a content change, it will invalidate the cache entries for
both domains, and thus the mirrored engines will serve correct content.
--
MichaelDaum - 28 Feb 2012
I wrote a little HOWTO for using Postgres at
Support.BestPracticeTip30.
I notice that when you fail to supply a user/pass, you get a meaningful error in apache log (but NOT the Foswiki error log?) however, if the DB has not yet been created, it just silently fails.
Some improved logging would help users who've neglected to create the cache database or mis-typed it in configure
--
PaulHarvey - 16 Mar 2012
trin.org.au dev server numbers:
# |
Min |
Mean |
sd |
Median |
Max |
Before -n 10 |
437 |
453 |
11.8 |
451 |
476 |
After -n 10 |
75 |
87 |
5.9 |
89 |
94 |
ab -c4 -n 20 was giving circa 8 requests/second, now 35/second.
--
PaulHarvey - 16 Mar 2012
On which kind of page are you testing? It is required to average on a wide range, including static topics, large topics as well as dynamic ones with some searches on them.
Also: there's a significant difference between pages that have dirty areas and those that dont. The latter can return a 304, the former not.
--
MichaelDaum - 16 Mar 2012
Btw: I was wondering wheter we should move the DBI settings from
{Cache}{DBI}
to
{DBI}
so that they can be used by other stuff in need of a DBI connection?
--
MichaelDaum - 16 Mar 2012
You're right, a single spot check is hardly scientific, but it was just to satisfy myself for comparison with the old cache. My ab test was on a page involving some sectional-includes (I guess ~6 parametrized
INCLUDE statements which build an HTML form), and a
SEARCH showing a page of 10 hits. Also our
WidgetsSkin, which itself does a bunch of
INCLUDEs, and a
SEARCH for children of the basetopic.
I'm not a DBI user (in Foswiki context anyway), so I'm not sure I can offer any advice here... my first reaction might be, "is the DBI connection to the cache DB also appropriate for other things" - I guess some people might want to take a more compartmentalized approach (security? load balancing? dunno).
Perhaps it could be
{DBI}{Cache}
,
{DBI}{Store}
, etc.
--
PaulHarvey - 16 Mar 2012
Well basically there are a bunch of plugins already that all come with their DBI configuration variables. So this starts getting redundant, even more when they all connect to the same database. Best would be to reuse the same connection and store for multiple purposes and standardize on the way the tables are named. For instalce the page cache uses the
{Cache}{DBI}{TablePrefix} = 'foswiki_cache'
setting.
Inverting it to a
{DBI}{Cache}{TablePrefix}
makes sense though, even more when the rest goes into
{DBI}{...}
anyway.
--
MichaelDaum - 16 Mar 2012
Yup, sharing the DBI connection is exactly why I made
DbiContrib. still - not important yet - once 1.1.5 is out the door, just having people run this cache so we can get it super stable it more important. We can coaless the rest over time.
(I'll certainly be running it on my dreamhost based wiki's, adding an Pluggable Access accellerator re-using the same connection, and then Paul and I will look at making a
MongoDB cache backend)
--
SvenDowideit - 18 Mar 2012