Forum OpenACS Development: whole page caching using memcached

I am wondering if anyone has thought about caching whole OpenACS pages with memcached and how you would go about it. Here are my assumptions:

a) I have a way to determine if an operation has an effect on the cached page. Read: e.g. I know that the list of projects needs to be recached the moment I add a new project.

b) I can use Naviserver with OpenACS as I have no intention to rewrite ns_memcache for AOLserver

Assume I have Naviserver running with OpenACS. Upon loading of the page I would use a special key syntax along with the page name to store the whole page as a key in memcached. Now, how do I do this? If I call a page, how can I store the generated HTML in memcached before it is returned to the end user? Can this be done using a filter?

Once it is in memcached I can use my nginx frontend to just fetch it from memcached and off I go. Furthermore, because of the key, I would know e.g. upon project creation to remove the pages that deal with project listings.

We could probably drive this further with SSI support in NGINX and a nice trick (not sure how) in OpenACS to server includes as SSIs.

I got inspired by this post, so you understand where I come from: http://blog.kovyrin.net/2007/08/05/using-nginx-ssi-and-memcache-to-make-your-web-applications-faster/

Collapse
Posted by Gustaf Neumann on
For typical OpenACS applications whole-page-caching has many problems and limitations. Keep in mind that the page does not only depend on the "application objects" (tracking the implications of operations especially on aggregating functions is hard) but as well on the user state (user_id, cookies, permissions). In case of personalized content (e.g. dotlrn, where essentially every user sees different content for one url) you have to construct quite complex keys containing the query and user context, which will be some work to get it right, especially if you would try to re-implement this in nginx. I have doubts that the number of successful hits in the cache would be high. Caching page fragments is another story, but that won't be of use in nginx, and doing this via ns_cache will be probably much faster on aolserver/naviserver.

We did some experiments with memcached/pgmemcache and aolserver a few years ago on our learn-system with mixed results. pgmemcache was needed in our case, since often only our stored procedures knew, what objects are affected by a change. For our applications the performance gain was very little (often not existing) in comparison with the classical approach of storing in the db + ns_cache (full-page caching was not applicable). My recommendation is to identify the bottlenecks of your application and improve there.

If you are not discouraged about page caching, you might find xowiki an easy animal to experiment with page caching. xowiki builds from every query a string, which is sent back to the user via a "delivery method" (normally ns_return, see method reply_to_user). It is easy to use alternative methods for specialized packages. The most important part is in xowiki/www/index.vuh

Collapse
Posted by Tom Jackson on

Hey, this isn't necessarily an answer to your question, but I was looking at the new AOLserver 4.5 sources yesterday. There is a new filter point. It is called prequeue. Example:

proc ::prequeue {} {
    ns_log Notice "running ::prequeue"
    return filter_ok
}

ns_register_filter prequeue GET /* ::prequeue

Note that you don't define the proc with the usual 'why' arg. At the moment I don't know if the prequeue filters are run with their own thread, or if the driver thread waits for the prequeue procs to run, but it looks like you can prevent the whole connection from running any further. It looks like there is a callback, but anyway, it could be an inexpensive way to return cached pages without going through any of the request processor code.