WordPress.org

Make WordPress Core

Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#15304 closed enhancement (wontfix)

New file-based persistent cache

Reported by: mrasnika Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.0.1
Component: Cache API Keywords:
Focuses: Cc:

Description

I've read about the shortcomings of the original file-based persistent cache, that's been ditched since 2.5; I've also checked the available file-based cache implementations (wp-file-cache, neosmart's re-implementation of the original, even w3-total-cache with the W3_Cache_File class) and they all seem to have the same drawback: they save each cached entry in a separate file. This means that each hit or miss requires reading and writing to the file-system, making this approach useless.

I have implemented a different approach towards file-based caching, which is a cross between the mem-based caching that is now in WP, and the file-based caching -- here's what I wrote in a reply to wp-hackers:

"I would guess that there would be some performance benefit if the "file cache" is in the form of "pure php", so when you have to use that cache you just include the file like any other php script you have included. That combined with var_export() and using just one file for the cache (instead one cache file per cache entry) probably is going to deliver better results. At least there is no penalty for serialization/unserialization, and in this way with the includes we are sort of hijacking the file-reading and evaluation of their content by PHP itself."

"What if all the cache entries are read/written in bulk ? Take the current implementation for example (the mem-based): it stores everything inside an array, so hits and misses only deal with that array. If we save that array (with all the cached entries inside it) to file when destroying the object (or with register_shutdown_function()), and then include it when instantiating it, we are going to skip all the file-system read and write operations. In the worst-case scenario there is just one include (on an absolute path to be faster than include_path-based), and one write to file when dumping the contents of the cache array. The rest is the same -- the add/replace/set/get cache functions use the cache array."

I've attached the implementation as an object-cache.php so it can be tested, but I think that it can be used not just in this plugin form, but also to replace the mem-based cache that's now inside WordPress: it has all the advantages of the memory-based cache, plus it is persistent between pageloads. Additionally as stated above we are using only core php features like includes and var_export(), and there is no performance penalty for serialization/unserialization.

Attachments (1)

object-cache.php (13.3 KB) - added by mrasnika 9 years ago.

Download all attachments as: .zip

Change History (10)

@mrasnika
9 years ago

#1 @mrasnika
9 years ago

I forgot to mention that the point of this implementation is to have an affordable and well-performing cache for WordPress on shared hosting where "exotic" solutions like APC/xcache/eAcc/Memcached are really rare.

#2 follow-up: @scribu
9 years ago

Why not package it as a plugin first, to get some real testing?

#3 @scribu
9 years ago

You still need to read the file on each page load, but with your approach, instead of reading only what you need, you have to read the whole cache, which can get pretty huge.

So, this would lead to worse performance than with WP Super Cache, for example.

Also, PHP's file parsing isn't free, especially since the file could get pretty huge.

#4 @scribu
9 years ago

In other words, this doesn't solve anything, since the file still needs to be transferred over a slow connection, in the case of remote file systems.

#5 follow-up: @Denis-de-Bernardy
9 years ago

  • Resolution set to wontfix
  • Status changed from new to closed

If I recall correctly, the file-based object cache was dumped because some hosts (Dreamhost?) were complaining about excessive amounts of file writes due to it. If, for any reason, a plugin triggers regular writes on page loads, the suggested implementation leads us straight back to step 1.

Also, the suggested implementation is not thread safe. If you've two concurrent page loads that the first setting A, the other setting B, the mutex makes it so that the cache will automatically contain stale data in A or B depending on which page suits down first. By contrast, memcached or apc would deal with that by storing A and B independently from the page load.

Closing...

#6 @Denis-de-Bernardy
9 years ago

  • Milestone Awaiting Review deleted
  • Version set to 3.0.1

#7 @westi
9 years ago

Caching backends don't (at this time) belong in core.

You need to pick the best one for your server setup.

#8 in reply to: ↑ 2 @mrasnika
9 years ago

Replying to scribu:

Why not package it as a plugin first, to get some real testing?

That is probably the best for now - indeed customer feedback will be helpful. Thanks for the tip ;)

#9 in reply to: ↑ 5 @mrasnika
9 years ago

  • Cc mrasnika added

Replying to Denis-de-Bernardy:

If I recall correctly, the file-based object cache was dumped because some hosts (Dreamhost?) were complaining about excessive amounts of file writes due to it. If, for any reason, a plugin triggers regular writes on page loads, the suggested implementation leads us straight back to step 1.

Also, the suggested implementation is not thread safe. If you've two concurrent page loads that the first setting A, the other setting B, the mutex makes it so that the cache will automatically contain stale data in A or B depending on which page suits down first. By contrast, memcached or apc would deal with that by storing A and B independently from the page load.

Yeah, but it is cache ;) Anyway, I see your point. For now better have that as a plugin to gain some customer feedback

Closing...

Note: See TracTickets for help on using tickets.