Where does APC store its opcode and user variable cache? - php

The reason I ask is because when using top I don't see a process for anything like APC. So I assume that the memory usage would be accounted for in an apache process.
Is that the case, and does that mean that the memory APC is using is replicated in each apache process, thereby taking up potentially much more memory than what was originally assigned to it?
If this is the case would memcache be a better solution, even if it's not being used on multiple loadbalanced servers?

APC uses shared memory to store its opcode cache. In the case of mod_php this memory is shared between all Apache processes. So a 30MB cache only takes up 30MB even if there are 5 Apache processes.
However, when using mod_php, each Apache process does waste a lot of resources as each process contains the PHP interpreter. Thus, when Apache serves static content (html, css, js, image files, etc) it uses a process with the full PHP interpreter loaded. To get around this, some people use FastCGI via mod_fastcgi or mod_fcgi. Using an opcode cache with FastCGI becomes a bit trickier.
There is currently no way to use memcache as an opcode cache. Even if there was, it would probably be slower than desired.

Besides being an opcode cache, APC also provides shared memory. That strongly suggests that it has its own internal shared memory system similar to memcached.

Related

Is there a way to define constants that persist in memory when PHP loads?

Is there a way to define constants that boot into memory when the PHP process starts on the server? If so, can it be done with arrays, classes, and functions as well?
Before people start listing the different ways of declaring things that will be available across pages and scopes: I'm not asking this from a coding convenience, but rather a performance perspective.
It seems like a waste to keep loading things that never change, from pages or databases etc, on every script execution. Being a server-side process, I would think PHP has some way to read things into memory once and have them always available.
What you are looking for is an opcode cache. Opcode caches work by storing the compiled contents of PHP files in shared memory, then using that data to short-circuit the standard code parsing process when the file is included/required in the future.
The canonical opcode cache at this point is the PHP opcache extension, but a number of other opcode caches exist, including APC and XCache.
Opcode caches do not cache data from databases. There are other extensions which you can use to assist in this process, though, such as APCu which stores them in shared memory, or memcached which stores them in an external process. None of this is automatic, though, as caching data from a database requires some application knowledge to know what is useful to cache, and to handle cache invalidation when you update the database.
In general php is a single treaded environment and it does not actually run constantly (unlike java). Php starts working only when receives a command to do so. Then it parses the code into opcode and eventually executes it. And that technically happens on every request (or CLI command).
However, there are several ways how you can cache the opcode with not much efforts with APC: http://www.php.net/manual/en/book.apc.php

Will the PHP 5.5 opcache be shared across processes with FastCGI (mod_fcgi)?

My website is running on PHP 5.5 with FastCGI (mod_fcgi). I'm aware that other opcache types (like APC) doesn't work well as memory is not shared between php-cgi processes (here).
I'm using PHP 5.5 built-in OPcache. Is the memory shared between processes or this is exactly the same problem of APC/Xcache with mod_fcgi?
Is there any way to test it?
I have never understood why this was even entertained as a possibility, it is not a realistic possibility:
Both APC and Opcache have several forms of shared memory, their defaults and the most suitable kind is mmap'd memory, but for all kinds of strange reasons they need to support inferior kinds, none of these inferior kinds leave a possibility (even an unrealistic one) for this to work.
When it comes to mmap...
APC
If you do not provide a file mask APC uses anonymous shared mapping, you cannot share this across distinct process boundaries, not possible.
If you do provide a file mask, APC uses unsynchronized shared mapping, it doesn't make sense to try and share that across distinct process boundaries since it will nearly always contain a corrupted shadow of the mapped memory, that's the nature of unsynchronized.
Opcache
Doesn't provide you with any of the non-options that APC tried to provide, all mapping is done anonymously.
Solution
Use a sane webserver such as nginx/lighthttpd, and use fpm, included with PHP.
FPM's process model allows the child processes it forks to have a common cache, problem solved, applicable to both APC and Opcache.

PHP spiking cpu usage

I was testing my site with Jmeter to see how hundred threads would affect site performance and tested it with apache and mod_php and nginx with fastcgi. I noticed that the bottlebeck was always cpu in both apache and nginx. when I was looking at spu usage in nginx setup I could see that php cgi processes were taking all cpu.
What can I do to decrease php cpu usage?
The reason PHP is taking up more resources than your web servers is that PHP is doing a lot more work, and does so in an intepreted language (Apache and Nginx is both compiled into CPU instructions).
The first step is to implement an opcode cache (I recommend APC since it's easily installed and maintained by the PHP people). This will cache a "compiled" version of your scripts which will remove a big bit of the script execution.
The only other way to decrease CPU usage is to make your code more effective. Try to identify bottlenecks (large arrays and other data structures may be the first to check out) and find ways to make those parts of the code perform better.

mod_fcgid with php opcode caching

I have been using apache web server with mpm-worker and mod_fcgid.
I have read about mod_fcgid that it can not make use of opcode caching.
http://www.brandonturner.net/blog/2009/07/fastcgi_with_php_opcode_cache/
apc cache module seems to be enabled in my php configuration.
I am not sure if my spawned php codes are never shared.
Should I remove APC? Does it have any overhead?
I am not sure if my spawned php codes are never shared.
You might find this question helpful.
Should I remove APC? Does it have any overhead?
As for the overhead, if you have n processes, then you'll have n caches.
It's not space efficient but it might still help reducing CPU cycles tho.
It does use opcode caching, but the caches are not shared between the PHP processes, so they will be cached once for each process. It's definitely still worth using APC.
Having read the article, I'll throw my own $0.2c in here w/regards to fgcid vs fastcgi. We initially deployed a solution much like that described in the article, using fastcgi and having the PHP process spawn multiple children. This was an attempt to work around the problems of sharing the cache.
However, we experienced periodic complete lockups with this solution; the PHP process would hang and fastcgi would fail to detect it, resulting in our entire app hanging for all users.
We've switched to fcgid again and the lockups ceased entirely. There is some overhead with a cache per process, but fcgid will only spawn new PHP processes when it needs to, so in practice the overhead is minimal.
We also use the user cache with APC, not just the opcode cache, so for us the tradeoff is definitely worth it (cached data means less work on the server, cached opcodes mean less work on the server) so CPU usage is definitely reduced for a slight memory usage penalty.

PHP Opcode cached in hard disk?

I have websites developed in PHP. Im using Opcode cache.
But because Opcode cache like eAccelerator or APC is cached in RAM, I needs too much RAM.
So Im looking for any project or technique which cache the PHP Opcode in hard disk.
Thanks so much
(my website is not generate money, so Im thinking about cheaper solution)
all op-code caches allow you to configure the maximum size of shared memory used (look for a configuration option with shm - for SHared Memory - in the name, eg. apc.shm_size). so you can control that they don't use too much ram.
some caches also allow you to cache on disk instead/besides of caching in ram:
eAccelerator
the question is if a small amount of shared memory or a disk only cache gains you anything in performance compared to plain php without op-code cache. as always when using a cache, you should benchmark this.

Categories