|
No we haven't tried that. Unfortunately we cannot use a memory based cached. following code works under heavy load with apache bench : <?php
require_once 'Zend/Cache.php';
$frontendOptions = array(
'lifetime' => 7200
);
$backendOptions = array(
'cache_dir' => '/tmp/' // Directory where to put the cache files
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
if(!$result = $cache->load('myresult')) {
$result='foobar foobar foobar...';
$cache->save($result, 'myresult');
echo "NOT CACHED";
} else {
echo "CACHED";
}
I tried with "ab -c 50 -n 1000" (50 concurrent request) I got : "Failed requests: 0" If you try the same example with a lifetime of 2 seconds for example (to get a NOT CACHED during the test), you have some "Failed requests because of length which is not the same "CACHED" or "NOT CACHED"). So IMHO, File backend works under heavy load. Have try to activate logging ? If it's a file locking problem (because of specific software or hardware...), you can try to desactivate file locking in backend options ? Can you try my example on your servers ? Hi, no problem for me please activate logging I attach the code that i have used too: $logger = new Zend_Log(); $logger->addWriter($writer); $logger->log('>>>>START ' . $session_id, 1); $frontendOptions = array( $backendOptions = array( $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); if(!$result = $cache->load('myresult')) { Using the code above I was still getting the following results in ab: This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Benchmarking www.intrebari-daniel.ro (be patient) Server Software: Apache/2.2.3 Document Path: / Concurrency Level: 50 Connection Times (ms) Percentage of the requests served within a certain time (ms) I have tried using Sqlite engine and the cache was fine Thank you I'm definitely seeing the same thing here. Not entirely sure whats happening, but the file backend is removing metadata and cache files before they expire under high load. I can reliably reproduce this using the testcase code using ab and -n 1000 -c 4 (instead of -c 50). PHP 5.2.6 running as FastCGI Still happens with file_locking turned off. Here is a better log, with the actual Zend_Cache_Backend_File logging output Here is another log, this time with file_locking turned on The problem still happens with file locking on and both read and write control turned off. Not sure whats going on here but it basically makes the File Backend completely useless under any kind of load. pretty standard linux setup, 2.6.18 on an ext3 fs. OK, I've found the problem and a fix. I will post a patch after I've had a chance to verify it and clean it up. I've attached a patch to fix this issue. apply with patch -p0 Basically there were some implementation details of the reading and writing of files here that were very vulnerable to race conditions. I have tested this on linux 2.6 and windows, it performs perfectly in both cases. here is a summary of the changes in the patch:
That seems to fix it. I have added the patch to Zend library. Thanks a lot I will get a contributor license agreement sent to Zend today so that the patch can be applied for 1.5.3 Also, just a quick note, the likely reason Fabian didn't see the problem with his testcase, is the amount of data being cached in his testcase is small enough that it fits in the normal fwrite/fread buffers and thus minimizes the race condition a bit, using Caval's test case will hit the problem every time. Also this patch improves performance greatly in the case of a php backend that does not have a particular cache id in its internal metadatas array, as it no longer rewrites the metadatas file to disk in this case. Can't reproduce this even with a 10 MB cache file !
some interesting things in the patch anyway I'm reviewing it The ab failed request is not what shows you the bug activate a logger for the cache and log cached vs not cached in a log file. What is happening is under load, without my patch, you will get constant cache misses as the metadatas and cache files are trampled due to race conditions. see the log files I have attached to the bug. 2008-06-25T22:46:59+00:00 ALERT (1): >>>>START My test case {{ <?php define('ROOT_DIR', '/var/www/test'); require 'Zend/Log.php'; $logger = new Zend_Log(); $logger->addWriter($writer); $logger->log('>>>>START ' . $session_id, 1); $frontendOptions = array( $backendOptions = array( $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); if (!$result = $cache->load('myresult')) { The part of the patch "added third optional parameter to _setMetadatas, to disable writing metadata to disk, eliminating the needless rewriting of metadatas file during _getMetadatas" is commited into the trunk and into the 1.5 branch Other parts should be commited only into the trunk (for 1.6 release) Could you try the head of the 1.5 branch to see if the problem is fixed for you ? other part of the patch commited to the trunk (for 1.6 release) good job thanks Tested 1.5 branch snapshot, definitely helps reduce the problem quite a bit, but does not totally eliminate it as the full patch does. Thanks a ton for your work, and I really look forward to the next 1.5 release and more so to 1.6!! Updating for the 1.6.0 release. |
||||||||||||||||||||||||||||||||||||||||||||
Seems to be a file locking problem , have you tried such a test with a memory based backend ? (APC, Memcached ...)