mod_fcgid with php opcode caching - php

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.

Related

How can I prevent memory exhaustion using a CakePHP application?

I am on a VPS server (Quad core with 768MB of RAM. I am running Apache and using APC as my default caching engine) . I get around 2000 visitors per day with a maximum of 100 concurrent visitors.
According to CakePHP DebugKit, my most memory intensive pages use around 16MB and the other pages average at around 10MB.
Is this memory usage normal?
Is it normal for my memory to bottleneck at 2000 visitors per page?
Should I consider upgrading my plan to 2GB RAM?
I also noticed that the View rendering is taking up most of the memory, around 70% on most pages.
I am monitoring my resource usage, when I have around 50 or more concurrent users, I am getting 0 free MB left.
Thank you
You should also check your other processes. From my experience, MySQL takes up more memory than anything else on any stack that I run. You should also implement better page caching so that PHP doesn't need to be touched when it isn't absolutely necessary. But Apache is also a memory hog that needs to be fine tuned. If you want to stick with Apache, then run Varnish in front of it.
Also, keep APC, but also add Memcached. It's much faster.
If your site has a spike-load that brings it to zero memory, then, if you can, consider launching extra instances of the server and doing a sort of round-robin (if the VPS is cloud-hosted and this is possible). If the load is constant, then definitely upgrade.
#burzum is completely right, however, that you should just switch to nginx. It's far, far better than Apache at this point. But, just to put you on the right track, quite a few people run nginx as a reverse proxy in front of Apache, and while that does speed up the server, it's entirely unnecessary because nginx can do pretty much anything you need it to do without Apache. Don't bother using Varnish in front of nginx either because nginx can act as its own reverse proxy.
Your best bet is to implement nginx with apcu (upgrade php to 5.5 if possible for better performance) and use memcached, and implement nginx's native microcaching abilities. If your site is heavy on read and light on write, then you might notice that everything is taken care of by nginx just retrieving a cached copy from memcache. While this helps with memory, it also helps with processing. My servers' CPUs usually have a 3-5% usage during peaks.
Is this memory usage normal?
Yes, it doesn't seem to be high for a normal CakePHP application.
Is it normal for my memory to bottleneck at 2000 visitors per page?
I guess yes, I'm not a "server guy".
Should I consider upgrading my plan to 2GB RAM?
I would try switching to Nginx first. Apache is a memory eating monster compared to Nginx, just search for a few banchmarks, a random one I've picked by a quick search is from this page.
Overall Nginx should provide you a much better performance. At some stage I would consider updating the memory but try Nginx first.

How apache runs PHP for pages [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
Imagine there is a PHP page on http://server/page.php.
Client(s) send 100 requests from browser to the server for that page simultaneously.
Does the server run 100 separate processes of php.exe simultaneously?
Does it re-interpret the page.php 100 times?
The answer is highly variable, according to server config.
Let's answer question 1 first:
Does the server run 100 separate processes of php.exe simultaneously?
This depends on the way PHP is installed. If PHP is being run via CGI, then the answer is "Yes, each request calls a separate instance of PHP". If it's being run via an Apache module, then the answer is "No, each request starts a new PHP thread within the Apache executable".
Similar variations will exist for other web servers. Please note that for a Unix/Linux based operating system, running separate copies of the executable for each request is not necessarily a bad thing for performance; the core of the OS is designed such that in many cases, tasks are better done by a number of separate executables rather than one monolithic one.
However, no matter what you do about it, having large numbers of simultaneous requests will drain your server resources and lead to timeouts and errors for your users. This is why it is important for your PHP programs to finish running as quickly as possible. Do not write PHP programs for web consumption that are slow to run; if you're likely to have a lot of traffic, you need to test for performance as much as you do for functionality. Having your programs exit quickly will dramatically reduce the likelihood of having a significant number of simultaneous requests, which will obviously have a big impact on your site's performance.
Now your second question:
Does it re-interpret the page.php 100 times?
For a standard PHP installation, the answer here is "Yes it does, and yes it does have a performance impact."
However, PHP provides several Caching solutions that are designed specifically to mitigate this. The main options are APC and the Zend Cache, either of which can be installed as standard modules. Using these modules will mean that PHP caches the interpreted code, so it can be run much faster for subsequent calls.
The Zend Cache will be included as part of the standard PHP installation as of the forthcoming PHP 5.5 release.
Apache2 has multiple different mode to work.
In "prefork" (the most commonly used) mode, Apache will create process for every request, each process will run a own php.exe. Config file will assign a maximum number of connections (MaxClients in httpd.conf), Apache will only create MaxClients. This is to prevent memory exhaustion. More requests are queued, waiting for the previous request to complete.
If you do not install opcode cache extensions like APC, XCache, eAccelerator, php.exe will re-interpret the page.php 100 times.
It depends.
There are different ways of setting things up, and things can get quite complex.
The short answer is 'more or less'. A number of apache processes will be spawned, the PHP code will be parsed and run.
If you want to avoid the parsing overhead use an opcode cache. APC (Alternative PHP Cache) is a very popular one. This has a number of neat features which are worth digging into, but without any config other than installing it it will ensure that each php page is only parsed into opcode once.
To change how many apache services are spawned, most likely you'll be using MPM Prefork. This lets you decide if how you want Apache to deal with multiple users.
For general advice, in my experience (small sites, not a huge amount of traffic), installing APC is worth doing, for everything else the defaults are not too bad.
There are a number of answers to this. In general, Apache will create a process for an incoming request, so it is possible that 100 process are created. However, a process takes time to create, so it might be that by the time a process has finished and died, one of those 100 connections comes in a fraction of a second later (since 100 connections at exactly the same time is very rare indeed, unless you're Google).
However, let us imagine that 100 processes do really need to be held in memory simultaneously, but that there is only room for 50 in available server RAM. In that case, 50 connections will be served, and 50 will have to wait for processes to die and be re-spawned. Thus, a random half of those requests will be delayed, though if a process create-process-die sequence only takes a fraction of a second, they won't have to wait very long. This is why, when improving server capacity, reducing your page load time is as important as adding more RAM - the sooner a process finishes, the sooner a new one can take its place.
One way, incidentally, to reduce load time is to spawn a number of PHP processes and hold them in memory. This is the basis of FastCGI (or fcgid, which is compatible). Rather than creating and killing a process for every request, a process is spawned in memory immediately and is re-used for several requests. For PHP, these are usually configure to die after a certain number of page requests (e.g. 1000) as historically PHP has had quite a lot of memory leaks (the more a process is reused, the worse the memory leaks get).
You ask if a page is re-interpreted for every request. Normally yes, but if you also run a PHP Accelerator, then no - the byte-code that PHP compiles to is cached and reused. Thus, mixing the FastCGI approach with an accelerator can make for a very speedy server indeed. Standard PHP does not come with an accelerator, but Zend Cache is scheduled for inclusion into the PHP core.

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.

Where does APC store its opcode and user variable cache?

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.

PHP vs. long-running process (Python, Java, etc.)?

I'd like to have your opinion about writing web apps in PHP vs. a long-running process using tools such as Django or Turbogears for Python.
As far as I know:
- In PHP, pages are fetched from the hard-disk every time (although I assume the OS keeps files in RAM for a while after they've been accessed)
- Pages are recompiled into opcode every time (although tools from eg. Zend can keep a compiled version in RAM)
- Fetching pages every time means reading global and session data every time, and re-opening connections to the DB
So, I guess PHP makes sense on a shared server (multiple sites sharing the same host) to run apps with moderate use, while a long-running process offers higher performance with apps that run on a dedicated server and are under heavy use?
Thanks for any feedback.
After you apply memcache, opcode caching, and connection pooling, the only real difference between PHP and other options is that PHP is short-lived, processed based, while other options are, typically, long-lived multithreaded based.
The advantage PHP has is that its dirt simple to write scripts. You don't have to worry about memory management (its always released at the end of the request), and you don't have to worry about concurrency very much.
The major disadvantage, I can see anyways, is that some more advanced (sometimes crazier?) things are harder: pre-computing results, warming caches, reusing existing data, request prioritizing, and asynchronous programming. I'm sure people can think of many more.
Most of the time, though, those disadvantages aren't a big deal. You can scale by adding more machines and using more caching. The average web developer doesn't need to worry about concurrency control or memory management, so taking the minuscule hit from removing them isn't a big deal.
With APC, which is soon to be included by default in PHP compiled bytecode is kept in RAM.
With mod_php, which is the most popular way to use PHP, the PHP interpreter stays in web server's memory.
With APC data store or memcache, you can have persistent objects in RAM instead of for example always creating them all anew by fetching data from DB.
In real life deployment you'd use all of above.
PHP is fine for either use in my opinion, the performance overheads are rarely noticed. It's usually other processes which will delay the program. It's easy to cache PHP programs with something like eAccelerator.
As many others have noted, PHP nor Django are going to be your bottlenecks. Hitting the hard disk for the bytecode on PHP is irrelevant for a heavily trafficked site because caching will take over at that point. The same is true for Django.
Model/View and user experience design will have order of magnitude benefits to performance over the language itself.
PHP is a language like Java etc.
Only your executable is the php binary and not the JVM! You can set another MAX-Runtime for PHP-Scripts without any problems (if your shared hosting provider let you do so).
Where your apps are running shouldn't depend on the kind of the server. It should depend on the ressources used by the application (CPU-Time,RAM) and what is given by your Server/Vserver/Shared Host!
For performance tuning reasons you should have a look at eAccelerator etc.
Apache supports also modules for connection pooling! See mod_dbd.
If you need to scale (like in a cluster) you can use distributed memory caching systems like memcached!

Categories