Closed (fixed)
Project:
Drupal core
Version:
x.y.z
Component:
base system
Priority:
Critical
Category:
Feature request
Assigned:
Reporter:
Created:
5 Jul 2006 at 13:30 UTC
Updated:
13 Sep 2006 at 09:30 UTC
Jump to comment: Most recent file
Comments
Comment #1
killes@www.drop.org commentedhere is a version for 4.7 for people who want to test it.
Comment #2
killes@www.drop.org commentedI've taken the opportunity to have a look at drupal.org's cache table.
It has about 75000 entries.
Over 70000 are filter entries
The maximum of cached pages I've seen is about 2000.
there are between 130 and 500 menu cache entries.
The filter and page cache change quite often, the menu cache seems quite stable.
So the table which would profit most from this patch is the proposed cache_menu table which probably could be fully cached by mysql's query cache.
The page cache would profit by being in a smaller table on its own where the select should be faster.
Probably only a test on a live site can tell us if and what this patch can achieve.
Comment #3
moshe weitzman commentedI think the logic behind this patch is quite sound, and the benefits might be significant. Good idea.
I would be OK with $domain being the 2nd param in cache_get() and defaulting it to 'default'. That way, you don't have to patch in a few places. No biggie.
Comment #4
chx commentedThis is very sound, later on we could do some magick so that we can memcached per domain. I run memcached for sessions, data cache, menu cache and url aliases, so i think this avenue worth pursuing.
Back to this patch here, I can't agree more.
Comment #5
dries commentedThis is one of the patches that need a fair amount of testing on busy sites. We need numbers so let's see if we can test it on drupal.org. If you run a busy Drupal site, please help test this patch. If there is no notable performance improvement, the patch probably isn't worth keeping. Point is, we need more than one website to evaluate this.
We'll want to collect information about MySQL's cache miss ratio. If you want to help, here is how you can compute your site's cache miss ratio. (There might be better ways to analyse this.)
These are the current drupal.org cache statistics (not using Gerhard's patch). I'd think that 'Qcache_inserts' equals the absolute number of cache misses; after all, every cache miss results in the entry being inserted in the cache. Looking at these numbers, Drupal.org has a cache miss ratio of 21% (and a cache hit rate of 79%).
Of all the missers, 'Qcache_lowmem_prunes' seems to denote the 'capacitcy cache missers': 16025991 / (16025991 + 168641389) = .08. That is, 8% of all the misses are the result of the cache being too small. 92% of the cache misses are due to the queries not being in the cache (because the cache got flushed -- partially of in full).
Clearly, Gerhard's patch aims to make partial cache flushes 'smaller' (reduce the number of cache entries that get evicted), so if that 92% goes down, the total cache miss rate should go down as well, and performance should increase. At least, that is the theory, and ultimately, what we'd like to see confirmed.
Anyway, as for the patch itself, I'd document the rationale and workings in the code comments. Without the proper MySQL cache background, this code is plain weird. After all, we're working around a MySQL /limitation/ (i.e. MySQL's aggressive/conservative cache flusing behavior). :)
Hoping this gets some people up to speed with this patch.
Comment #6
killes@www.drop.org commentedI've tested the patch for a few hours on drupal.org (and broke drupal.be, sorry guys).
There wasn't an obvious improvement. This could be due to a configuration problem which I've outlined here:
http://lists.drupal.org/private/infrastructure/2006-July/005766.html
Needs more testing.
Comment #7
killes@www.drop.org commentedI just want to mention that the cache hits vs inserts ratio is meagre. We need to fix our query cache setup before we can test this patch.
Comment #8
moshe weitzman commentedplease have a look at the pain people are experiencing at http://drupal.org/node/73604. I think the patch here can help them. Specifically, once we split out the filter and menu tables, we focus cache_clear_all() for thesze cases to perform a TRUNCATE TABLE instead of DELETE FROM which will be much easier on the DB.
Comment #9
nicholasthompsonI'm currently experiencing a problem as described here: http://drupal.org/node/74136
Do you think this patch could solve the issue?
Comment #10
m3avrck commentedOoooh, I really like the sound of this one!
Comment #11
agentrickardThis would be a good change, and having the $domain present would make batch deletion from the filecache more efficient. It would also make implementing the object_cache much easier. (See http://drupal.org/node/74020)
One dumb question: why name the variable $domain? I find that variable name confusing. Wouldn't $type or $table be preferable?
One suggestion: For object caching (or other cache extensions), we would need an easy method for expanding the allowable $domain variables. Currently, I would need to patch this code by adding more switch statements to cache_get_table().
Comment #12
killes@www.drop.org commentedhaving more tables is probably a good idea. No particular reason for the $domain name.
Another advantage of this patch will be that the key we use (cid) will be shorter for the tables. no need to prefix each filter cache entry with "filter:" anymore. This will lead to a smaller index and both faster inserts and selects. It will also save some diskspace/memory.
Since we've decided to not focus on query cache issues we'd maybe test the patch on a pgsql site.
Comment #13
Amazon commentedFor people looking to test this:
http://cvs.drupal.org/viewcvs/drupal/contributions/modules/devel/generat...
Add pages.
Enable caching on your site. Then crawl the site to fill up the cache: wget -r --delete-after --cookies=off http://example.com
insert into cache (cid, data) select concat('filter:1:', MD5(RAND())), data from cache where cid like 'filter:';
I'll test more and report back.
Comment #14
moshe weitzman commented@killes - are you planning on collecting measurements for this. the separate tables will make flushing the cache much faster. see #8
Comment #15
killes@www.drop.org commentedGuess I could, yes. I am, not so much concerned about the flushing, as this often happens at the end of page requests, I am more interested in faster selects and inserts.
Comment #16
killes@www.drop.org commentedrunning now.
Comment #17
gerhard killesreiter commentedFound some evidence that this patch is a good thing, read here:
http://lists.drupal.org/archives/development/2006-08/msg00091.html
Comment #18
pwolanin commentedminor nit-pick:
Your suggested documentation for cache_get(), etc says:
However, your retrival of the cached variables uses:
and the actual work is done by the function below, which sends everything other then the above 4 to the "default" cache. So, why not suggest/use NULL or '' as the first parameter to cache_get? The documentation for cach_get(), etc. needs to specify the case @param = none of these.
Comment #19
killes@www.drop.org commentedI think I have further evidence that this patch is a good thing(tm). Attached is the two-week graph of the load of our database server. The patch is runnign on drupal.org since 13:00 on Wednesday 2nd. The graph runs on EST, I have indicated the time since when the patch was applied on the graph. It might be wishful thinking but I think the load after thatis on average lower than on the left.
Comment #20
moshe weitzman commentedi agree. this is not wishful thinking. the period after the patch demonstrates an average low that is unmatched in the lifetime of the chart.
Comment #21
killes@www.drop.org commentedYeah, I think we can rule out wishful thinking, see attached graph.
Comment #22
killes@www.drop.org commentedForgot the description:
Black is the week before this, red is this week. The arrow again indicates when I applied the patch.
Comment #23
killes@www.drop.org commentedI am now convinced that this is a "must have" for the next Drupal version, so here is a patch for HEAD including sql updates.
Comment #24
pwolanin commentedas above, documentation is missing for: @param $domain == '', 'default', etc.
Comment #25
chx commentedI agree this is a must. Hence the priority change.
A small code change, though is needed.
this lets you add cache tables. Maybe CCK or views wants its own cache table. Or another huge module will arise after we release... This is less code than a switch and faster...
Comment #26
pwolanin commentedmodified patch as per chx's suggestion, tried to clean up Doxygen comments and caught a couple stray pre-patch uses of cache_set/get/clear_all
Comment #27
pwolanin commentedHmmm, still needs work. The menu caching isn't working right. The cache doesn't seem to get clear appropriately. For example, i enabled the locale module, and the menu items didn't appear and weren't accessible.
Comment #28
pwolanin commentedAlso, with this patch, can/should cache_clear_all() be modified to use TRUNCATE for totally clearing tables?
Comment #29
pwolanin commentedfor some reason, the this doesn't seem to work: cache_clear_all('menu', '', TRUE);
It does seem to work in this form: cache_clear_all('menu', ':', TRUE);, since all the cache IDs include a colon.
Also, extended cache_clear_all() so that a call with no parameters clears expired/temporary entries from all the predefined tables.
PS, also changed the system update # istarting above since someone else had committed a duplicated.
Comment #30
pwolanin commentedlooks like the update should really be numbered 1006. see: http://drupal.org/node/64212#comment-122346
Comment #31
catchapologies for cross posting. It sounds like this would help us out a lot if we're having the same issue as described here: http://drupal.org/node/73604 (my original forum post is here: http://drupal.org/node/78424)
We have a busy site (c.1.5 million pages/month although we've had a lot of downtime the past three months so probably more like 800k ish atm), and one that's experiencing '000s of 404s per day due to our being in the early stages of moving everything to drupal. Our drupal install has c.8000 nodes and c.100,000 comments. Cache table generates a lot of overhead and needs to be repaired and optimised every few hours before everything crashes.
Would be happy to help test the patch against 4.7.3 but won't be able to look at it until Sunday. I'd also be happy to give one of the developers working on this root access to the machine in order to try it out yourselves if you're so inclined - you'd get much better feedback that way since I'm very much a beginner at server administration. Will give it ago myself either way though when I get a chance and post up the results.
Comment #32
pwolanin commented@killes - is this a 'feature' or a 'bug'.
Attached patch is updated to current HEAD (minimally tested, however). Also added check so that if $wildcard == TRUE and $cid == '*', the effect is to simply delete everything in the table, rather than doing the string match.
Comment #33
killes@www.drop.org commentedI've updated the patch after a review by Dries.
Main changes:
- changed order of cid and "domain"
- made "domain" "table". We can avoid the lookup function then.
- introduced "truncate table" instead of "delete from table". "truncate table" is much faster for large tables. It exists for both MySQL and Postgres but it is not ANSI SQL. Maybe it should become a db API function.
- Changed the wirldcard match from substring to right hand substring.
I have also changed some cache_clear_all calls and fixed a few bugs while doing so.
cache_clear_all is now an alias to cache_clear_all('*', 'cache_page', TRUE);
This keeps the patch nice and small.
Also added some docs.
Comment #34
pwolanin commentedabove you say:
Is that really the behavior you want? This would seem to mean that the code would no longer respect/use the minimum cache lifetime, right? Wouldn't you want cache_clear_all(NULL, 'cache_page')?
Comment #35
killes@www.drop.org commentedPeter, you are right. Also rerolled to keep up with CVS.
Comment #36
killes@www.drop.org commentedRe-rolled to include more docs, has a cron hook to expire filter items. cache_clear_all should be renamed in a clean-up patch, it doesn't clear all of the cache, usually.
Comment #37
m3avrck commentedReviewed the code, looks very good to me. Nothing stands out as needing anymore work. I'd say this is RTBC but perhaps another review is needed :-)
Comment #38
dries commentedLatest patch looks a lot cleaner to me!
+ * - such smaller tables can be held in RAM by the SQL serverI wonder if that is true.
It would be good if someone could proof-read the phpDoc and double check whether the API is sound. Otherwise looks ready to be committed.
Comment #39
killes@www.drop.org commentedWell, the statement about the RAM is so general that is is most certainly true but also completely useless. :p
We also still need to load info from most tables so Drupal doesn't have any advantage from the size of the individual tables. Re-rolled without this line.
Comment #40
killes@www.drop.org commentedneclimdul found bug, fixed in this version.
Comment #41
neclimdul+1
Looks good. I love how this is setup allowing contrib to add cache tables and use the api. The docs seemed pretty clear to me. The only odd thing was in cache_clear_all the table arguement is mandatory but it says "if set".
Comment #42
killes@www.drop.org commentedchanged docs to: "Mandatory argument if $cid is set."
Comment #43
dries commentedCommitted to CVS HEAD! Thanks.
Comment #44
killes@www.drop.org commentedThanks!
A follow-up patch will deal with renaming cache_clear_all, see
http://drupal.org/node/81461
Comment #45
(not verified) commented