You are here: Foswiki>Tasks Web>Item11549 (06 Nov 2018, MichaelDaum)Edit Attach

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
Reported By: MichaelDaum
Waiting For:
Last Change By: MichaelDaum
Use DBI to capture the dependencies among wiki pages have a BDB fallback for low-tech setups.

  1. make Foswiki::PageCache a virtual class DONE
  2. implement Foswiki::PageCache::DBI DONE
  3. test against mysql ... (works, but not covered by unit tests yet)
  4. test against sqlite ... (works, but not covered by unit tests yet)
  5. test against postgresql ... (works, but not covered by unit tests yet)
  6. implement Foswiki::PageCache::BDB ... not worth it
  7. removal of all Foswiki::Cache classes DONE
  8. adjust of Fosiwki.spec and configure checkers: only offer the caching settings when the perl classes are available actually. DONE
  9. compare performance wrt speedup and throughput DONE
  10. documentation DONE

-- MichaelDaum - 22 Feb 2012

Awesome! Would love to try a mongo impl, for those who might already be running it smile

-- PaulHarvey - 22 Feb 2012

Benchmarking random topics from the System web using siege.

  • 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

  • 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, 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, all content is also served by, 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 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
Topic revision: r40 - 06 Nov 2018, MichaelDaum
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy