Thread
-
Re: Database Caching
F Harvell <fharvell@fts.net> — 2002-03-05T16:35:32Z
On 01 Mar 2002 10:24:39 +0500, Hannu Krosing wrote: > ... > > > I don't see how result caching can be a win, since it can be done when > > needed anyway, without adding complexity to the database engine. Just > > have the application cache the result set. Certainly a web server could > > do this, if needed. > > More advanced application server can do it all right. But you still need > sound cache invalidation mechanisms. > > > If there were a way to mark a database as read only (and this could not > > be changed unless the entire database is shut down and restarted in > > read/write mode) then there might be some utility to result set cache. > > Otherwise, I think it will be wasted effort. It might be worthwhile to > > do the same for individual tables (with the same sort of restrictions). > > But think of all the effort that would be needed to do this properly, > > and what sort of payback would be received from it? > > The payback will be blazingly fast slashdot type applications with very > little effort from end application programmer. > > > Again, the same goals can easily be accomplished without having to > > perform major surgery on the database system. I suspect that there is > > some logical reason that Oracle/Sybase/IBM/Microsoft have not bothered > > with it. > > I think they were designed/developed when WWW was nonexistent, and > client-server meant a system where client and server where separated by > a (slow) network connection that would negate most of the benefit from > server side cacheing. On todays application server scenario the client > (AS) and server (DB) are usually very close, if not on the same computer > and thus effectively managed cache can be kept on DB to avoid all the > cache invalidation logic going through DB-AS link. > > ... You have identified one of the most valuable reasons for query/result caching. As I read the threads going on about caching, it reminds me of the arguments within MySQL about the need for referential integrity and transactions. Yes, the application can do it, however, by having the database do it, it frees the application programmer to perform more important tasks (e.g., more features). Your insights about the caching, etc. in the older, legacy databases is very likely the case. With the development of high speed networking, etc., it is now very feasible to move the caching closer to the sources of change/invalidation. Quite frankly, while certainly there are literally millions of applications that would find minimal value in query/results caching, I know that, at least for web applications, that the query/results caching _would_ be very valuable. Certainly, as has been pointed out several times, the application can do the caching, however, utilizing todays "generic" tools such as Apache and PHP, it is relatively difficult. By moving caching to the database server, there is little that needs to be done by the application to realize the benefits. For example, with my typical application, as a straight dynamic application, the process would be approximately: 1) receive the request "http://www.xyz.com/index.php" 2) query the current page contents from the database: select * from table where dateline = '2002-03-05'; 3) begin the HTML output 4) loop through the select results printing the contents 5) complete the HTML output With caching within the database, this would likely achieve performance good enough to serve millions of requests per day. (This is the case for some of our sites using Intersystems Cache which does do query caching and serves over 2 million page views per day.) Without the database caching, it is necessary to have the application perform this function. Because of the short life of an Apache/PHP process, caching needs to be performed externally to the application: 1) receive the request "http://www.xyz.com/index.php" 2) check the age of the cache file (1min, 5min ???): 3) if the cache is not fresh: 3.1) lock the cache file 3.2) query the database 3.3) begin HTML output to the cache file 3.4) loop through select results 3.5) complete the HTML output to the cache file 3.6) unlock the cache file 4) open the cache file (i.e., wait for locked file) 5) read/passthrough cache contents (Please note that this is one, simplified way to do the caching. It assumes that the data becomes stale over time and needs to be refreshed. It also uses a file cache instead of a memory cache. Certainly things could be made more efficient through the use of notifications from the database and the use of shared memory. Another path would be to have an external program generating the pages and then placing the "static" pages into service (which requires changes to apache and/or the OS due to cache file invalidation during the generation process). Both paths make the application more complex requiring more programming time.) It is possible to have an application server do this caching for you. Of course, that in turn has its own complications. For applications that do not need the added "features" of an application server, database caching can be a big win in both processing/response time as well as programmer time. Thanks, F Harvell
-
Re: Database Caching
Rod Taylor <rbt@zort.ca> — 2002-03-05T17:46:27Z
> Certainly, as has been pointed out several times, the application can > do the caching, however, utilizing todays "generic" tools such as > Apache and PHP, it is relatively difficult. By moving caching to the > database server, there is little that needs to be done by the > application to realize the benefits. PHP has an amazingly easy to use Shared Memory resource. Create a semaphore, and an index hash in position 0 which points to the rest of the resources. On query lock memory, lookup in index, pull values if it exists otherwise run db query and stuff values in. The tricky part is expiring the cache. I store a time in position 1 and a table in the database. To see if cache should be expired I do a select against the 'timer' table in the db. If it's expired, clear cache and let it be rebuilt. A trigger updates the time on change. Doesn't work well at all for frequent updates -- but thats not what it's for. Took about 15 minutes to write the caching mechanism in a generic fashion for all my applications. Step 2 of my process was to cache the generated HTML page itself so I generate it once. I store it gzip compressed, and serve directly to browsers which support gzip compression (most). Pages are stored in shared memory using the above mechanism. This took about 40 minutes (php output buffer) and is based on the uniqueness of the pages requested. Transparent to the application too (prepend and append code elements). (Zend cache does this too I think). Anyway, I don't feel like rewriting it as non-private code, but the concept is simple enough. Perhaps Zend or PEAR could write the above data lookup wrappers to shared memory. Although you don't even have to worry about structures or layout, just the ID that represents the location of your object in memory. It can serve a couple million per hour using this on a E220 with lots of ram -- bandwidth always runs out first. Anyway, first suggestion is to buy Zend Cache (if available) to cache entire HTML pages, not to cache db queries. Even the great Slashdot (which everone appears to be comparing this to) uses a page cache to reduce load and serves primarily static HTML pages which were pregenerated. I agree with the solution, I don't agree with the proposed location as caching DB queries only solves about 1/4 of the whole problem. The other being network (millions of queries across 100mbit isn't fast either), and genereation of the non-static page from the static (cached) query. Build a few large (10k row) tables to see what I mean about where the slowdown really is.
-
Re: Database Caching
Steve Wolfe <steve@iboats.com> — 2002-03-05T19:13:15Z
> > > I don't see how result caching can be a win, since it can be done when > > > needed anyway, without adding complexity to the database engine. Just > > > have the application cache the result set. Certainly a web server could > > > do this, if needed. There are a couple of catches with that idea. First, we have thirty+ applications that we've written, and trying to go back and patch the caching into all of them would be much more work than just doing it in the DB. Secondly, changes to the data can be made from psql, other apps, or from triggers and hence, there is no reliable way to deal with cache expiration. Not only that, but if you have a pool of web servers, applications on each one can be inserting/updating data, and none of the other machines have any clue about that. Really, doing it in PG makes a lot of sense. Doing it outside of PG has a lot of problems. At one point, I was resolved that I was going to do it in middleware. I sat down and planned out the entire thing, including a really nifty hash structure that would make cache expiration and invalidtion lightning-fast... but I had focused entirely on the implementation, and when I realized all of the drawbacks to doing it outside of the backend, I scrapped it. That's the first time I've ever really wished that I was a C programmer.... In the worst-case scenario (never repeating a query), result caching would have a very small overhead. In any semi-realistic scenario, the benefits are likely to be significant to extraordinary. steve