APC (Alternative PHP Cache)

      6 Comments on APC (Alternative PHP Cache)

ApcgraphicA quick update to close (I hope) the book on PHP caching add-ons. As I mentioned before, I’ve been having a lot of trouble getting long-term use out of eAccelerator. Today I downloaded and installed the latest version of APC (Alternative PHP Cache) and thus far it’s working well.

I made a discovery during the compilation and configuration process for APC that may well explain the problems I was having with eAccelerator. Turns out a BSD-derivative UNIX (which describes Mac OS X Server) defaults to a shared memory segment size of 4 megabytes. That’s small compared to Linux 2.2 kernels which have a default maximum of 32 Mb. When I configured eAccelerator, I stupidly used 16Mb for my shared memory segment size then later increased it to 32Mb (more must be better, right?). Doh! I now assume it ran for weeks until it crossed the 4Mb threshold then overwrote memory shared by some other process—“bye bye” server.

If you’re curious, you can issue this command on your Mac to see the value of the shared memory segment size.

/usr/sbin/sysctl -a | grep shmmax

which should return:

kern.sysv.shmmax: 4194304

You’ll see the same value on a machine running either Mac OSX or OSX Server (10.4 in both cases).

Having gotten suddenly smarter, I set APC’s shared memory segment size to the correct value of 4 megabytes and instructed the cache to use up to 8 segments (yielding a 32Mb cache). Based on the readout I’m getting from the monitoring utility that ships with APC, I’ll never use anywhere near 32Mb for the cache. Here are the settings from /etc/php.ini

extension=apc.so
apc.enabled=1
apc.shm_segments=8
apc.optimization=0
apc.shm_size=4
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1

What sort of performance measures are we seeing with APC? After just over 6 hours of operation:

  • Cache hits: 95443
  • Cache misses: 77
  • Request rate: 4.29 cache requests per second
  • Cache size: 4.4 Mb

The hits vs. misses numbers are astounding, but they’re also very much driven by this server’s particular workload (more on that later). The last value is what I want to talk about first. We’ve crossed the 4Mb threshold and it only took 6 hours. If the shared memory overrun theory is correct, how could eAccelerator have run for a couple of weeks before hitting that limit? Good question. My current guess is that eAccelerator’s cache files aren’t the same size as APC’s (I know, for example, that eAccelerator was optimizing the opcodes while APC doesn’t do that) thus it took longer to hit the 4Mb limit.

Getting back to the hits vs. misses—it’s really because of the application we’re running. This server hosts a modified version of the Scout Internet Portal and the structure of that app differs from your typical server’s mix of php scripts. SPT executes a massive include stanza every time a page loads. Net effect: within the first 2 minutes of operation our cache has probably seen 98% of the php code it’s going to see. After an hour, there’s only miniscule growth in the size of the cached code. Combining APC with the Scout CWIS truly begs a YMMV.

One final takeaway: if you run SPT, you owe it to yourself and your users to investigate a PHP cache.