php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57569 High Fragmentation degrading performance
Submitted: 2007-03-09 15:00 UTC Modified: 2007-03-14 06:55 UTC
From: apc at tequilasolutions dot com Assigned:
Status: Closed Package: APC (PECL)
PHP Version: 5.2.1 OS: FC4
Private report: No CVE-ID: None
 [2007-03-09 15:00 UTC] apc at tequilasolutions dot com
Description:
------------
Since the upgrade from 12p2 to 13 my server fragmentation just builds and builds from the off.  Eventually pages are taking twice as long as usual to load, I'm guessing this high fragmentation has something to do with it.  Percentage isn't necessarily high, depends how full the cache is at the time but number of fragments is high and this definitely didn't happen with 12p2.  I store lots of user entries, usually peaking around 32000.  The miss rate is always zero, this can't be right?

  apc.stat=1
  apc.enabled=1
  apc.shm_segments=1
  apc.optimization=0
  apc.shm_size=128
  apc.ttl=7200
  apc.user_ttl=7200
  apc.num_files_hint=1024
  apc.user_entries_hint=32768
  apc.mmap_file_mask=/tmp/apc.XXXXXX
  apc.enable_cli=0
  apc.filters="download_blob.php"

made with:

./configure --enable-apc --enable-apc-mmap --with-apxs




Reproduce code:
---------------
http://web01.tequilasolutions.com/apc_cache.php

Expected result:
----------------
User cache miss rates and low fragementation as in 12p2

Actual result:
--------------
High frags, degraded performance

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-03-09 17:06 UTC] apc at tequilasolutions dot com
Made a quick file to attempt a cache defrag, unsafe I know no locking error checking etc... fragmentation doubled.  Discovered just adding to user cache causes frags every time.  Try adding random data in a loop and you get mega fragmentation.

<?
	$info = apc_cache_info("user");
	$count = 0;
	$tmp_dir = "/home/sukerman/tmp/cache_defrag";
	// store cache
	foreach($info['cache_list'] as $entry){
		$name = $entry['info'];
		$data = apc_fetch($name);
		if (!$data) continue;
		$fp = fopen("$tmp_dir/$name","w+");
		fwrite($fp,$data);
		fclose($fp);
	}
	apc_clear_cache("user");
	// rewrite cache
	$d = dir($tmp_dir);
	while (false !== ($entry = $d->read())) {
		if ($entry=="." or $entry=="..") continue;
		$data = file_get_contents("$tmp_dir/$entry");
		apc_store($entry,$data);
		unlink("$tmp_dir/$entry");
	}
	$d->close();
?>
 [2007-03-10 15:34 UTC] apc at tequilasolutions dot com
Appreciate it if someone can look at this, or say they can't for now so I can switch back to 12p2.   I'll leave it on 13 so it can be reproduced for now and can do a live comparison with 12 or give you access to the user cache if someone wants to get in touch.  My server restarts as soon as frag % hits 50% but earlier it was running with 44000 user cache entries and 70000 fragments.
 [2007-03-10 16:01 UTC] apc at tequilasolutions dot com
Server was starting to crawl, I've switched back to 12p2, but you can get a screen here http://www.tequilasolutions.com/frags.gif and I'll switch back to 13 if you want to see it live.

Cheers,

Steve
 [2007-03-10 16:06 UTC] apc at tequilasolutions dot com
but... check it theres not much fragging going on now we are back on 12p2 until the cache gets low on memory then it start to really fragment which is why I have a script to restart httpd when we hit 50% frags, but generally it runs for 9-10 hours before this happens.

http://web01.tequilasolutions.com/apc_cache.php
 [2007-03-10 16:09 UTC] apc at tequilasolutions dot com
ok....

final thing I'll say on this,

pages now loading at 0.05 secs, were taking 0.89 once new apc had been running for 3 hours so definitely an issue here.

Thanks, sorry to complain, love your work ;-)
 [2007-03-13 05:54 UTC] marcus at synchromedia dot co dot uk
I'm seeing this too. Initial page hits peg apache at 100% CPU 
for 30-45 sec and consumes a bit over 100Mb (might be 
segfaulting?). Subsequent requests are delivered in 0.04 sec!

I'm also seeing terrible fragmentation - thousands of 16-byte 
entries. My 128Mb allocation got up to 73,000 fragments!

Turning APC off results in page deliveries dropping to a 
consistent ~0.5 sec with no initial hit.
 [2007-03-13 05:57 UTC] gopalv82 at yahoo dot com
This seems serious, I'll take a closer look and give you a backpatch onto 3.0.13 if I can fix it (CVS has too many "new & untested" features).
 [2007-03-13 18:46 UTC] gopalv82 at yahoo dot com
After hours of tracing down 16 byte blocks, this looks like a likely culprit ... 

+++ apc_compile.c       13 Mar 2007 23:44:48 -0000
@@ -1828,6 +1828,7 @@
 static void my_free_zval_ptr(zval** src, apc_free_t deallocate)
 {
     my_destroy_zval_ptr(src, deallocate);
+    deallocate(src);
 }
 /* }}} */

Try testing it if you want ... I'll take a couple of days to get it "properly" tested.
 [2007-03-14 04:28 UTC] apc at tequilasolutions dot com
I've edited apc_compile.c

/* {{{ my_free_zval_ptr */
static void my_free_zval_ptr(zval** src, apc_free_t deallocate)
{
    my_destroy_zval_ptr(src, deallocate);
    deallocate(src);
}
/* }}} */

Frags are building from the restart I'll leave it running for you, this doesnt seem to have fixed it.

http://web01.tequilasolutions.com/apc_cache.php

Thanks,

Steve
 [2007-03-14 04:37 UTC] gopalv82 at yahoo dot com
Are you on x86_64 and are you just populating the user cache with strings ?
 [2007-03-14 04:46 UTC] apc at tequilasolutions dot com
...having said that I was getting 2 frags per user entry before, its now on 8000 entrys 500 frags so its better than before.   Got virtually no frags with 12p2 though think theres a bit more to it.
 [2007-03-14 04:57 UTC] apc at tequilasolutions dot com
user password is admin/gopal I store array with three entries, name, udt, data.

array (
  0 => 'snowsport_england_gateway',
  1 => 1173865754,
  2 => 's:4:"NULL";',
)

Sometimes data is a gzcompressed string.  Let me know when you've had a look so I can change my password

Thanks.

Steve
 [2007-03-14 05:25 UTC] gopalv82 at yahoo dot com
Took a look, nothing unusual there ... 

Trying to figure out where your particular 16 byte block is coming from. Disable apc opcode cache with apc.cache_by_default = Off and see if you can still cause fragmentation.

The 16 byte sounds really suspicious because only sma_allocate(0) would be able to create a 16 byte block in sma. Might want to put an assert(size > 0) in the sma_allocate function (apc_sma.c) to trap an illegal call if it comes through.
 [2007-03-14 05:36 UTC] apc at tequilasolutions dot com
Disabled opcode cache, still getting 16 byte frags
 [2007-03-14 05:43 UTC] apc at tequilasolutions dot com
Added the assert still getting 16B blocks, where will the assert message appear?, nothing in access logs or /log/messages as yet.
 [2007-03-14 06:11 UTC] gopalv82 at yahoo dot com
I've nearly got a workable test case here. I'm doing the following here and going to leave it thrashing for ~20 mins.

In apc_sma.c inside sma_allocate add an alignword() wraparound for sizeof(block_t), like this.

 -        if (cur->size == realsize || (cur->size > (sizeof(block_t) + realsize))) {
 +        if (cur->size == realsize || (cur->size > (alignword(sizeof(block_t)) + realsize))) {
            prvnextfit = prv;
            break;
        }

That's how the 16 byte segments are being dropped around, I think. That can take a bit of tweaking to minimize small fragments (say, realsize + block + 128 before allowing a split).

That should sort of work ... but that bit of code hasn't changed in a while.
 [2007-03-14 06:49 UTC] apc at tequilasolutions dot com
I've made those changes, bingo !! seems to be fixed.

Thanks

Steve
 [2007-03-14 06:53 UTC] apc at tequilasolutions dot com
Just to be noted perhaps, the first change with the assert seemed to help somewhat as well, not sure if the first one is still required as I've removed it and the frags issue seems to be gone.
 [2007-03-14 06:54 UTC] gopalv82 at yahoo dot com
Fixes into CVS HEAD

http://news.php.net/php.pecl.cvs/7416
http://news.php.net/php.pecl.cvs/7418
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat May 18 16:01:36 2024 UTC