[wp-hackers] Caching as part of the core
Dion Hulse (dd32)
wordpress at dd32.id.au
Tue Jul 24 03:20:27 UTC 2012
On 24 July 2012 11:31, Bryan Petty <bpetty at bluehost.com> wrote:
> On 07/23/2012 12:25 PM, Michael Van Winkle wrote:
>> However, I'm not sure I understand why the existing object cache is
>> insufficient for delivering that fragment. Can we get more specific
>> about what the failure of the current object caching api is? I think
>> a MUCH bigger issue is theme/plugin developers generally lack of
>> awareness and/or concern for caching and performance.
>
> Personally, I believe the failure is mainly in the fact that the
> existing object cache isn't persistent. A cache that doesn't have the
> ability to persist across requests is really just a glorified static
> class variable / global variable. It doesn't actually provide anything
> helpful that you couldn't already do without it.
>
> Of course fixing that does absolutely require an outside service such as
> memcache/XCache/APC, or just fall back on file. There's two main
> arguments I keep seeing against expanding the existing object cache to
> support these:
>
> 1. Most shared hosting providers don't supply any of those services.
> 2. This should be implemented by plugins (and is currently).
>
> At Bluehost, even though we don't offer memcache directly, a number of
> customers have still compiled and run it themselves on our servers
> anyway (and we do enable the PHP memcache extension). On the other hand
> though, nearly every shared hosting provider does support file write
> permissions, so at the very least, the file cache backend would work out
> of the box on 99% of shared hosting accounts.
>
> Putting that aside, it's possible to not only enable support for all of
> the backends mentioned above in core WP, but to do so in a completely
> backwards compatible way with the existing object cache, *and* also do
> so without adding a single extra option to the installer *or* the
> administration panel.
>
> Those on shared hosting providers without support for any of those
> backends (including file cache, assuming no write permissions)
> wouldn't even notice support for this was added. And for those that do
> support it, it could either be automatically configured during install
> (though I wouldn't recommend that - beyond enabling the file cache at
> least), or it could be a couple incredibly simple options in
> wp-config.php (as opposed to looking for and installing some possibly
> defective/dangerous 3rd party plugin/drop-in).
>
> All web application frameworks provide this API exactly as I described
> here and they do it because most web applications need it, and while
> WordPress isn't trying to be a web application framework, it's not built
> on top of one, so it has to provide it's own. I do actually believe that
> this doesn't belong in WordPress, but that's only because it belongs in
> a web framework. It's not like WordPress will ever be built on one
> though, so there's really not much choice than to add it.
>
> As for implementing it in a plugin, is there really more than one way to
> write an API around a cache engine? There really isn't, they're all the
> same, they just store the objects in different ways. So what is the
> point of it even being a 3rd party drop-in or plugin?
>
> To get back to your concern that the main issue is a lack of awareness
> for caching or performance, I think part of that also has to do with the
> fact that the existing object cache is barely helpful in the first place
> because it's not persistent. When plugin authors know they can cache
> data for longer than a single request (and that it will work on nearly
> all WP installations by default without requiring additional plugins),
> they'll be much more likely to make use of the caching engine since it
> will actually make way more of a difference.
To me, this post (And most of this thread honestly) screams "I don't
know how the current system works, so I think we should add something
else instead" by people who are either a) not writing this stuff b)
don't configure servers, and c) don't know the history here
Back in WordPress < 2.5, there was a file-based Object cache included
in WordPress by default, however, it suffered one major drawback..
although when enabled it reduced the reliance upon MySQL and
regenerating objects constantly, on many hosts it was inefficient and
would *slow the site down instead*.
See http://core.trac.wordpress.org/ticket/5570 for when it was
removed, although the ticket doesn't mention the speed issues I
mentioned
The object cache is designed for fast persistent storage, and to
prevent requerying of data - As it is, a simply per-request in-memory
cache it saves a lot of queries from hitting MySQL because the result
of the functions are already cached.
Filesystems are often not fast, infact, they're REALLY slow, in many
cases, querying the data directly from MySQL was faster (thanks to
it's in-memory caches - query cache and table indicies in memory, etc)
- but a SQL is almost always slower than a key-value lookup in a
proper memory cache (Since it has to parse the query, check no data
changed, etc)
File based caches are good, but not for storing hundreds of small
chunks of data the pageload needs.. For example, loading the wp-admin
dashboard on my site requires 475 cache gets, Loading the front end?
1102 cache gets, a large number of those are duplicated (for example,
the alloptions and notoptions cache's) but the majority are not,
storing 500+ chunks of data on the filesystem, reading them in,
deserializing them, that takes time.. especially when it's a Network
based filesystem (NFS) which many shared hosts use - Many have local
caches for commonly accessed files (ie. all the WordPress .php's) but
many won't cache 10,000 small files (per site!) locally.. leading to
extra latency to retrieve the data.
You could say "Well, Just split the data over multiple files!".. Tell
you what, when you stop coming across MySQL databases that are
consistently less than 10MB in size, and not reaching >100MB, let me
know.. and maybe a dozen small efficient files will be usable.
Lets also not get into the race conditions of file-based caches, the
high latency increases chance conditions where 2 pageloads will do an
update_option, and clobber eachother since the files took so long to
update for the other process to notice (Yes, this is possible
currently with MySQL, the difference is, it's a much smaller chance it
happens)
It's true that since the file cache was introduced (And later removed)
that WordPress has become much more complex, the data structures being
stored are larger, the number of keys being set are larger (as there's
permutations of data with the number of options we now have for
functions), so potential issues back then, are perhaps compounded
today and will be even worse..
Full page caching to a static file is significantly different from the
above scenario, for that, you're storing and retrieving a SINGLE file
(So even if it's hitting the disk, it isn't loading the 100+ WordPress
files, nor having to load PHP in some cases). This is significantly
faster and more efficient *on pretty much all hosts*.
So, Why not include a full-page cache in WordPress then? Well.. several reasons:
1. We have Plugins for this - the fact we have at least 5 different
plugins which do this in different ways goes to show something: There
is never a right way, nor a wrong way, every plugin suits different
use-cases
2. Users loose a lot of dynamic abilities in their sites (regardless
of if you guys don't do that, or know you can use workarounds), face
it, most sites do NOT need full page caching, I can't count the number
of *fast* WordPress sites I come across which do not have a caching
plugin installed.. WordPress isn't as slow as many people like to
believe
3. Not all server configurations are the same, we can't expect
everyone to be running Apache (Infact, IIS support is going great, and
looks like nginx support is "getting better"(I'm referring to rewrite
rule generation for config files here - see trac)), all 3 of these
major web servers require a different configuration method for direct
serving of static .html files, and although it can be done within PHP,
that's still an overhead many people don't want (thus,they use a
plugin to override it.. etc..)
4. Adding it to core requires that it be compatible with many
configurations, this means often using a slower method if it means
it's more compatible, plugins don't generally have this problem, and
can throw a bazillion configuration options in instead.. But it's
also an extra thing the core team have to support (I can guarantee
you, If a *basic* file cache was added to WordPress, most of the
plugin authors who write this stuff would leave it to us to maintain..
Keeping caching in a plugin means that updates can be pushed
separately from WordPress, and is the direction WordPress has been
going for a long time (Just look at the Debug functionality for
WordPress for example - It all requires a plugin, same as caching,
different databases, etc)
And finally,
5. What are you trying to fix?
It really sounds like this is an attempt to work around Lazy
developers, or web admins, or people who don't know what they're
doing.. Doing it for them is not always the best option, education is
better.
To shift the discussion a bit, This probably heads back to the idea of
the plugins repo having better categories of plugins, and WordPress
suggesting people install a plugin from each (ie. Anti Spam, Caching,
Social, This, that, and the other)
post-finally.. Some links.
If you really want a disk based object cache, have at it:
http://wordpress.org/extend/plugins/wp-file-cache/ - be warned, it may
slow your site down if it's a shared server, or has a bad disk/io
cache
A quick overview of the slow down caused by the file-based cache:
http://www.viper007bond.com/2010/08/10/why-wordpress-doesnt-have-built-in-persistent-caching/
A thread when it was introduced:
http://lists.automattic.com/pipermail/wp-hackers/2005-November/003122.html
More information about the wp-hackers
mailing list