Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Page cache in PHP that handles concurrency?

Tags:

php

caching

I've read previous answers here about caching in PHP, and the articles they link to. I've checked out the oft-recommended Pear Cache_Light, QuickCache, and WordPress Super Cache. (Sorry - apparently I'm allowed to hyperlink only once.)

Either none deal with concurrency issues, or none explicitly call out that they do in their documentation.

Can anyone point me in the direction of a PHP page cache that handles concurrency?

This is on a shared host, so memcache and opcode caches are unfortunately not an option. I don't use a templating engine and would like to avoid taking a dependency on one. WP Super Cache's approach is preferable - i.e. storing static files under wwwroot to let Apache serve them - but not a requirement.

Thanks!

P.S. Examples of things that should be handled automatically:

  1. Apache / the PHP cache is in the middle of reading a cached file. The cached file becomes obsolete and deletion is attempted.
  2. A cached file was deleted because it was obsolete. A request for that file comes in, and the file is in the process of being recreated. Another request for the file comes in during this.
like image 445
WalterGR Avatar asked Aug 04 '09 08:08

WalterGR


People also ask

What is page caching in PHP?

A cache is a collection of duplicate data, where the original data is expensive to fetch or compute (usually in terms of access time) relative to the cache. In PHP, caching is used to minimize page generation time.

Does PHP get cached?

PHP by itself does not do caching. But there are opensource frameworks to let the programmer design their code to work this way. In other words, it lets the code check if the data has already been retrieved before it goes and fetches it again, which is a relatively slow process since it has to query the database.

How do I cache PHP files?

To generate the cache file, we use fopen() to open the write file for writing, fwrite() out the contents of our output buffer, then close the handle. Finally, we use include($cachefile) again so that users always see the output as if we hadn't had to generate it from scratch.


3 Answers

It seems PEAR::Cache_Lite has some kind of security to deal with concurrency issues.
If you take a look at the manual of constructor Cache_Lite::Cache_Lite, you have those options :

fileLocking enable / disable fileLocking. Can avoid cache corruption under bad circumstances.

writeControl enable / disable write control. Enable write control will lightly slow the cache writing but not the cache reading. Write control can detect some corrupt cache files but maybe it's not a perfect control.

readControl enable / disable read control. If enabled, a control key is embeded in cache file and this key is compared with the one calculated after the reading

readControlType Type of read control (only if read control is enabled). Must be 'md5' (for a md5 hash control (best but slowest)), 'crc32' (for a crc32 hash control (lightly less safe but faster)) or 'strlen' (for a length only test (fastest))

Which one to use is still up to you, and will depend on what kind of performance you are ready to sacrifice -- and the risk of concurrency access that probably exists in your application.


You might also want to take a look at Zend_Cache_Frontend_Output, to cache a page, using something like Zend_Cache_Backend_File as backend.

That one seems to support some kind of security as well -- the same kinf of stuff that Cache_Lite already gave you (so I won't copy-paste a second time)


As a sidenote, if your website runs on a shared host, I suppose it doesn't have that many users ? So the risks of concurrent access are probably not that high, are they ?

Anyway, I probably would not search any farther that what those tow Frameworks propose : it is already probably more than enough for the needs of your application :-)

(I've never seen any caching mecanism "more secure" than what those allow you to do... And i've never run into some catastrophic concurrency problem of that sort yet... In 3 years of PHP-development)


Anyway : have fun !

like image 136
Pascal MARTIN Avatar answered Oct 11 '22 04:10

Pascal MARTIN


I would be tempted to modify one of the existing caches. Zend Framework's cache should be able to do the trick. If not, I would change it.

You could create a really primitive locking strategy. The database could be used to track all of the cached items, allow locking for update, allow people to wait for someone else's update to complete, ...

That would handle your ACID issues. You could set the lock for someone else's update to a very short period, or possibly have it just skip the cache altogether for that round trip depending on your server load/capacity and the cost of producing the cached content.

Jacob

like image 30
TheJacobTaylor Avatar answered Oct 11 '22 02:10

TheJacobTaylor


Concurrent resource creation aka cache slamming / thread race can be a serious issue on busy websites. That's why I've created cache library that synchronize read/write processes/threads.

It has elegant and clear structure: interfaces -> adaptors -> classes for easy extension. At github page im explaining in details what's the problem with slamming and how The Library is resolving it.

Check it here: https://github.com/tztztztz/php-no-slam-cache

like image 26
Tomasz Zadora Avatar answered Oct 11 '22 03:10

Tomasz Zadora