You want to cache a high-demand page for one minute or until new content is added, whichever is *longer* (updates are frequent, and would defeat the cache). You create a ZCache object such that it will be
<snip>
Thoughts?
This sounds like a neat approach. If I understand correctly, you might start a site using a (for example) DTML Method called: dtBigExpensivePage in a Folder called foo (e.g., http://machine.com/foo/dtBigExpensivePage Over time you learn that dtBigExpensivePage is, in fact, expensive to render. Sooo, you might create a ZCache object in Folder foo called dtBigExpensivePage and move the DTML Method dtBigExpensivePage into the ZCache (a folderish thing) object dtBigExpensivePage. As a result, you'd be able to access http://machine.com/foo/dtBigExpensivePage and get the cached rendering and maybe access: http://machine.com/foo/dtBigExpensivePage/dtBigExpensivePage to get the uncached rendition. Of course, this lets you, over time and selectively build cached renditions of expensive objects... Did I get that right? --Rob
Rob Page wrote:
Over time you learn that dtBigExpensivePage is, in fact, expensive to render. Sooo, you might create a ZCache object in Folder foo called dtBigExpensivePage and move the DTML Method dtBigExpensivePage into the ZCache (a folderish thing) object dtBigExpensivePage.
As a result, you'd be able to access http://machine.com/foo/dtBigExpensivePage and get the cached rendering and maybe access:
http://machine.com/foo/dtBigExpensivePage/dtBigExpensivePage to get the uncached rendition.
Of course, this lets you, over time and selectively build cached renditions of expensive objects...
That's basically what I was thinking, yes.
Evan Simpson wrote:
Rob Page wrote:
Over time you learn that dtBigExpensivePage is, in fact, expensive to render. Sooo, you might create a ZCache object in Folder foo called dtBigExpensivePage and move the DTML Method dtBigExpensivePage into the ZCache (a folderish thing) object dtBigExpensivePage.
As a result, you'd be able to access http://machine.com/foo/dtBigExpensivePage and get the cached rendering and maybe access:
http://machine.com/foo/dtBigExpensivePage/dtBigExpensivePage to get the uncached rendition.
Of course, this lets you, over time and selectively build cached renditions of expensive objects...
That's basically what I was thinking, yes.
Sounds like a good way to cache XML Documents renderings too! This sounds quite elegant as it'd work with most objects out of the box. There might be some interactions with acquisition that could muddle things, though.. Regards, Martijn
Martijn Faassen wrote:
Evan Simpson wrote:
Rob Page wrote:
Over time you learn that dtBigExpensivePage is, in fact, expensive to render. Sooo, you might create a ZCache object in Folder foo called dtBigExpensivePage and move the DTML Method dtBigExpensivePage into
the
ZCache (a folderish thing) object dtBigExpensivePage.
As a result, you'd be able to access http://machine.com/foo/dtBigExpensivePage and get the cached rendering and maybe access:
http://machine.com/foo/dtBigExpensivePage/dtBigExpensivePage to get the uncached rendition.
Of course, this lets you, over time and selectively build cached renditions of expensive objects...
That's basically what I was thinking, yes.
Sounds like a good way to cache XML Documents renderings too! This sounds quite elegant as it'd work with most objects out of the box. There might be some interactions with acquisition that could muddle things, though..
I agree. Right now I have to render everything to a dtml document and serve that up instead of the actual xml document. That seems to work pretty well, but a more straightforward way to cache things is certainly needed, especially if it lets me cache the results of individual objects that can then be included in other (non-cached) objects. As I understand it, this scheme would pretty much create a cached copy of the rendered object which would itself live in the ZODB. It seems like there is still a performance penalty with keeping the cached item in the ZODB though (even when the object is in-memory), for instance I can serve 30-40 concurrent static DTML Documents from ZServer on my machine, but when I render the same material to disk and serve from apache the performance leaps ahead. Maybe a top-level cache should bypass the ZODB altogether if it can, maybe an in-memory cache that sits in front of Zope which ZServer hits first to try and return pages from. If something moves into the ZCache, then it moves into the top-level cache, and requests for it are simply intercepted before zope gets hit. This wouldn't work for pages that render based on specific authorizations, etc... but those requests would just fall back to piecing together a page from pre-rendered parts in the secondary (in ZODB) ZCache. Or maybe I'm misunderstanding this altogether. Jason
On Tue, 14 Sep 1999, Jason Jones wrote: :As I understand it, this scheme would pretty much create a cached copy of :the rendered object which would itself live in the ZODB. It seems like there :is still a performance penalty with keeping the cached item in the ZODB :though (even when the object is in-memory), for instance I can serve 30-40 :concurrent static DTML Documents from ZServer on my machine, but when I :render the same material to disk and serve from apache the performance leaps :ahead. Maybe a top-level cache should bypass the ZODB altogether if it can, why not just use some separate subsystem for caching, eq. a squid in httpd accelerator mode? it would be necessary to set appropriate cache control headers and expiry dates. i think this would be possible with zope? peter. _________________________________________________ peter sabaini, mailto: c c c p@oeh.tu-graz.ac.at, http://oeh.tu-graz.ac.at/~cccp/ - - - - - - - - - - - - - - - - - - - - - - - - - Any sufficiently perverted technology is indistinguishable from Perl. (ca. a.c. clarke) -------------------------------------------------
----- Original Message ----- From: Peter Sabaini <cccp@oeh.tu-graz.ac.at> To: Jason Jones <jason_j@countermedia.org> Cc: <zope@zope.org> Sent: Tuesday, September 14, 1999 12:42 PM Subject: Re: [Zope] Cacheing
On Tue, 14 Sep 1999, Jason Jones wrote:
:As I understand it, this scheme would pretty much create a cached copy of :the rendered object which would itself live in the ZODB. It seems like there :is still a performance penalty with keeping the cached item in the ZODB :though (even when the object is in-memory), for instance I can serve 30-40 :concurrent static DTML Documents from ZServer on my machine, but when I :render the same material to disk and serve from apache the performance leaps :ahead. Maybe a top-level cache should bypass the ZODB altogether if it can,
why not just use some separate subsystem for caching, eq. a squid in httpd accelerator mode?
it would be necessary to set appropriate cache control headers and expiry dates. i think this would be possible with zope?
I'm not that familiar with squid. How would you sync expiration from squid with objects changing in zope? I don't want a hard time to expire, rather I want my cache to refresh its contents as my backend changes (for most objects, others will need a hard expire date). Would I need to programmatically remove cached items from squid when the ZODB is updated so that Zope gets hit and the cache reloaded, or can squid check against ZODB modification times to see that my objects have changed? Is it straightforward to do this? if it isn't then squid doesn't do me much good unless I render everything to the filesystem every time something changes. These might be dumb questions, but like I said I don't know that much about squid. I understand that it is a proxy server, but it doesn't have any zope integration does it? Thanks, jason
On Tue, 14 Sep 1999, Jason Jones wrote: :----- Original Message ----- :From: Peter Sabaini <cccp@oeh.tu-graz.ac.at> :To: Jason Jones <jason_j@countermedia.org> :Cc: <zope@zope.org> :Sent: Tuesday, September 14, 1999 12:42 PM :Subject: Re: [Zope] Cacheing : : :> On Tue, 14 Sep 1999, Jason Jones wrote: :> :> :As I understand it, this scheme would pretty much create a cached copy of :> :the rendered object which would itself live in the ZODB. It seems like :there :> :is still a performance penalty with keeping the cached item in the ZODB :> :though (even when the object is in-memory), for instance I can serve :30-40 :> :concurrent static DTML Documents from ZServer on my machine, but when I :> :render the same material to disk and serve from apache the performance :leaps :> :ahead. Maybe a top-level cache should bypass the ZODB altogether if it :can, :> :> why not just use some separate subsystem for caching, eq. a squid :> in httpd accelerator mode? :> :> it would be necessary to set appropriate cache control headers and :> expiry dates. i think this would be possible with zope? : :I'm not that familiar with squid. How would you sync expiration from squid :with objects changing in zope? I don't want a hard time to expire, rather I :want my cache to refresh its contents as my backend changes (for most :objects, others will need a hard expire date). Would I need to :programmatically remove cached items from squid when the ZODB is updated so :that Zope gets hit and the cache reloaded, or can squid check against ZODB :modification times to see that my objects have changed? Is it :straightforward to do this? if it isn't then squid doesn't do me much good :unless I render everything to the filesystem every time something changes. : :These might be dumb questions, but like I said I don't know that much about :squid. I understand that it is a proxy server, but it doesn't have any zope :integration does it? you could set a cache control header to "must-revalidate". a caching proxy then would check back with an "If-Modified-Since" request to see if the object was modified since the last request. zope / apache would have to provide "Last-Modified" headers in order to make this work. note that this isn't specific to squid. rather this would affect many kinds of caches and proxys. see http://www.mnot.net/cache_docs/ or the http protocol http://www.w3.org/Protocols/ heres an engine which checks for cacheability (http://www.zope.org is not...): http://www.ircache.net/cgi-bin/cacheability.py peter. _________________________________________________ peter sabaini, mailto: c c c p@oeh.tu-graz.ac.at, http://oeh.tu-graz.ac.at/~cccp/ - - - - - - - - - - - - - - - - - - - - - - - - - Any sufficiently perverted technology is indistinguishable from Perl. (ca. a.c. clarke) -------------------------------------------------
:These might be dumb questions, but like I said I don't know that much about :squid. I understand that it is a proxy server, but it doesn't have any zope :integration does it?
you could set a cache control header to "must-revalidate".
a caching proxy then would check back with an "If-Modified-Since" request to see if the object was modified since the last request.
zope / apache would have to provide "Last-Modified" headers in order to make this work.
<- snip ->
Thanks for the info, it was a good read. Unfortunately the cache_docs you mention state that the best way to cache dynamic content is to dump it to a static file. That's exactly what I'm trying to avoid. The second suggestion is to set an age related header. For the most part this will work well enough for me, but it's not an ideal solution. I really would like the if-Modified-since type of thing, but for that I would need to generate the validators and then test from zope when a request comes in and respond appropriately, which would mean dtml executing for each validation (I assume). I still think the best thing is some sort of cache between the webserver and zope that gets updated automatically on a zope object change. For instance, cacheable objects should cache themselves, just like ZClasses can catalog themselves, but the cache shouldn't be ZODB based. That way I could select files to cache, not worry about arbitrary modification times, not worry about generating static files and not worry about the ZODB slowing things down. Instead I could serve up pre-generated pages from memory like static pages, directly from apache or zserver or whatever (zope would have to be modified appropriately to check the cache first of course). It seems like having an object in a ZCache object could render that to a global dictionary with the url part as the key. Zope could then check the dictionary and if the key exists, send it out. If the page changes, then it gets recached and the dictionary updated. If the url isn't in the dictionary, then zope runs normally. This could be combined with standard expires type cacheing to work pretty well. Internally, zope could check the dictionary for cached object items (by url reference) when building pages that can't be fully cached, so that at least some parts of the page are cached. for instance: http://myserver/index.html could be fully cached, http://myserver/members/index.html could be partly cached - (the dtml document at http://myserver/members/content might be cached while the method http://myserver/members/authenticate isn't, and both are glued into the index.html files) and the pages like http://myserver/search/results could be cached based on a expires time, so that ZCatalog returned stuff that might change every minute or so could be cacheable Jason
On Tue, 14 Sep 1999, Jason Jones wrote: : :> :These might be dumb questions, but like I said I don't know that much :about :> :squid. I understand that it is a proxy server, but it doesn't have any :zope :> :integration does it? :> :> you could set a cache control header to "must-revalidate". :> :> a caching proxy then would check back with an "If-Modified-Since" :> request to see if the object was modified since the last request. :> :> zope / apache would have to provide "Last-Modified" headers in :> order to make this work. :> :> <- snip -> : :Thanks for the info, it was a good read. Unfortunately the cache_docs you :mention state that the best way to cache dynamic content is to dump it to a :static file. That's exactly what I'm trying to avoid. traditionally, yes ;) :The second suggestion :is to set an age related header. For the most part this will work well :enough for me, but it's not an ideal solution. I really would like the :if-Modified-since type of thing, but for that I would need to generate the :validators and then test from zope when a request comes in and respond :appropriately, which would mean dtml executing for each validation (I :assume). i would like zope to generate these headers which is possible i believe :) [snip] there are pros and cons to building a cache into zope and leaving caching to some external site (and they arent mutually exclusive). one of the pros for external caching is that this would also work for all kinds of proxies and browser caches. peter. _________________________________________________ peter sabaini, mailto: c c c p@oeh.tu-graz.ac.at, http://oeh.tu-graz.ac.at/~cccp/ - - - - - - - - - - - - - - - - - - - - - - - - - Any sufficiently perverted technology is indistinguishable from Perl. (ca. a.c. clarke) -------------------------------------------------
Jason Jones wrote:
From: Peter Sabaini <cccp@oeh.tu-graz.ac.at>
[snip]
On Tue, 14 Sep 1999, Jason Jones wrote:
:As I understand it, this scheme would pretty much create a cached copy of :the rendered object which would itself live in the ZODB.
Not in the ZODB -- in memory. The ZCache object would, of course, live in the ZODB and be demand loaded and unloaded like any other object. The actual cached text would be stored in a transient variable, and would evaporate if the ZCache object were unloaded. This is good, since Zope will only unload it if it's taking up space that more popular objects need (unless rendering the object is **very** expensive; what then?).
why not just use some separate subsystem for caching, eq. a squid in httpd accelerator mode?
Squid (or Apache) will work fine, but under very limited circumstances: o The cached object is a 'final' document, rather than a 'part' (eg. a banner or toolbar) o Your cache rules are *very* simple o You don't need authentication or side effects of the URL lookup o You're willing to explicitly kill the cache, or just wait, when you make changes
On Tue, Sep 14, 1999 at 02:24:21PM -0500, Evan Simpson wrote:
Jason Jones wrote:
From: Peter Sabaini <cccp@oeh.tu-graz.ac.at>
[snip]
On Tue, 14 Sep 1999, Jason Jones wrote:
:As I understand it, this scheme would pretty much create a cached copy of :the rendered object which would itself live in the ZODB.
Not in the ZODB -- in memory. The ZCache object would, of course, live in the ZODB and be demand loaded and unloaded like any other object. The actual cached text would be stored in a transient variable, and would evaporate if the ZCache object were unloaded. This is good, since Zope will only unload it if it's taking up space that more popular objects need (unless rendering the object is **very** expensive; what then?).
Then you fall back to the case we have now: the developer does 'ad hoc' caching, like the XML->DTML render someone else mentioned. If generating the rendered version is **very** expensive, it should live in it's own object in the ZODB. The developer can make her own 'rerender this object' method. I think it falls into the same class as caching at page boundries: nice but not compelling. Personally, I can't think of an example of an object that would be _that_ expensive to render: What sort of thing are you envisioning in that catagory, that wouldn't already be represented as it's own object? Ross -- Ross J. Reedstrom, Ph.D., <reedstrm@rice.edu> NSBRI Research Scientist/Programmer Computer and Information Technology Institute Rice University, 6100 S. Main St., Houston, TX 77005
"Ross J. Reedstrom" wrote:
On Tue, Sep 14, 1999 at 02:24:21PM -0500, Evan Simpson wrote:
[snip]
(unless rendering the object is **very** expensive; what then?).
[snip again]
Personally, I can't think of an example of an object that would be _that_ expensive to render: What sort of thing are you envisioning in that catagory, that wouldn't already be represented as it's own object?
<shrug> The possibility occurred to me, so I thought I'd mention it, but I like your solution just fine. The only example I can think of isn't necessarily *expensive* to render, it's just *unreliable*: Suppose you're drawing on other websites for content, as in a Slashbox. Contacting the other site can take an unpredictable amount of time, and may fail. If it fails, you don't want a broken object, you just want to keep the results of the last successful render. As you point out, in this situation it would probably be best to have a special object to explicitly store the result, and use some sort of scheduling mechanism to call a re-render-attempt method on it periodically.
On Tue, 14 Sep 1999, Evan Simpson wrote: [snip] :> > why not just use some separate subsystem for caching, eq. a squid :> > in httpd accelerator mode? : :Squid (or Apache) will work fine, but under very limited circumstances: : :o The cached object is a 'final' document, rather than a 'part' (eg. a banner :or toolbar) the cacheable object is a final document, but it could be cacheable if you have some least common denominator of the 'parts' (the assembled document would be as young as the youngest part). :o Your cache rules are *very* simple you would have to revalidate every object. :o You don't need authentication or side effects of the URL lookup there are cases where even authenticated sessions can produce cacheable objects, for instance static images. :o You're willing to explicitly kill the cache, or just wait, when you make :changes no, you just would have to tell the cache to look if the requested document is younger than the one cached. peter. _________________________________________________ peter sabaini, mailto: c c c p@oeh.tu-graz.ac.at, http://oeh.tu-graz.ac.at/~cccp/ - - - - - - - - - - - - - - - - - - - - - - - - - Any sufficiently perverted technology is indistinguishable from Perl. (ca. a.c. clarke) -------------------------------------------------
participants (6)
-
Evan Simpson -
Jason Jones -
Martijn Faassen -
Peter Sabaini -
Rob Page -
Ross J. Reedstrom