lammert - 4:51 am on Jul 26, 2010 (gmt 0)
The first main problem I have encountered is deciding how the PHP scripts will be run by Nginx.
Plain CGI: The oldest way to call scripts from a web server is with the CGI interface. This interface which was defined in the early nineties spawns an external process for every script which has to be executed. The interface is simple and inter-process communication is straightforward with only one process reporting it's output back to the calling web server when exiting. The main problem with old-fashioned CGI is however the overhead for every process call. During every call a separate process has to be started, the PHP script has to be interpreted, MySQL database connections have to be arranged and when the script exits, all memory has to be reclaimed by the operating system again.
This causes a significant overhead, especially on high-traffic servers. For the specific situation where I want to use Nginx, this might however be a solution, because the main reason to try the test with Nginx is to reduce memory overhead, not process overhead. If a PHP script grows big during execution, it will only occupy its memory during the execution of the script.
FastCGI: As an improvement of the plain CGI interface, the FastCGI interface has been developed. Instead of creating a single process for every script to be executed, the FastCGI interface controls a pool of waiting PHP instances which execute a script whenever the web server receives a request for it. The idea behind it is that there is no overhead anymore for creating and stopping a process and initializing the PHP interpreter. Also connections with a MySQL server can be maintained between script calls, lowering the overhead in the PHP to database communication. The drawback of this approach is that once a PHP instance grows large because it has executed a bulky script which needed a lot of memory to process, that memory will stay occupied until the PHP process is killed.
mod_php: The most common used method to execute PHP scripts currently is the mod_php module which plugs directly into Apache. Instead of executing PHP via an interface, PHP is integrated in the web server. Each Apache web server instance runs one PHP interpreter which causes the fastest possible response time, but also the largest overhead. On a website which mainly serves images and occasionally executes a script, this causes significant overhead regarding memory usage. Every instance of Apache will eventually grow big because of the script execution, even if it will only serve small images most of the time.
It is obvious that mod_php is not available as an Nginx plug-in, but both implementations of plain CGI and FastCGI can be used with this web server.
Comparing with Apache, using FastCGI will reduce the number of PHP capable processes sitting in memory, but it won't necessarily reduce the size of each single process. This is because the FastCGI PHP process uses the same technology to stay resident in memory and wait for new requests as the mod_php implementation does. The difference is that the each mod_php instance is glued to a web server instance while with FastCGI the number of available PHP processes is independently regulated from the number of web server processes. The gain in memory usage should therefore come from a better utilization of existing PHP processes, rather than a reduction of the size of each individual process.
Plain CGI execution has the advantage with Nginx that memory is only occupied by PHP during the execution of a script. If small script is executed the memory usage of that specific PHP instance will be fairly low and large scripts will only occupy memory during the execution phase of the script. The main disadvantage of process overhead is only relative in our specific situation. The website is dealing with a low amount of traffic, but each visit requires a significant amount of server side processing with a few scripts. The relative overhead of the startup of new processes is therefore relatively low, at least much lower than it is with a regular website which executes continuously a large number of small scripts.
The road plan as I have set it now is therefore the following.