Apache with fcgid: acceptable performance and better resource utilization

Sorry, this entry is only available in Brazilian Portuguese. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

Update May 2013: We no longer recommend fcgid ever since Ubuntu Server 12.04 was released. This is because that version has PHP-FPM, which provides every benefit that fcgid has, with the added advantage of a shared opcode cache for all processes. We will be writing a full article on PHP-FPM with Drupal in the near future (soon to appear at High Performance Drupal with Apache MPM Worker Threaded Server and PHP-FPM).

Most sites that serve large Drupal instances use Apache with mod_php. Although this is often the easiest and fastest option, it may not be the ideal situation in some cases. This article explains fcgid, a way to run PHP other than mod_php, how to get it configured, and what are the advantages and disadvantages of it.

Apache’s mod_php

Apache’s mod_php is the most widely used mode for PHP with Apache. mod_php itself is the entire PHP interpreter embedded in each Apache process that gets spawned. This provides performance and stability benefits, e.g.

  • No need to call an external process (e.g. CGI).
  • No need to communicate with another process via sockets (e.g. Fast CGI).
  • The APC cache is shared by all Apache processes.

It also has some disadvantages

  • The memory footprint per Apache process is large, specially when sites indulge in contributed modules.
  • If Apache is serving static content, e.g. images and CSS files, it still has to spawn large processes because of the embedded PHP interpreter.

CGI

CGI (Common Gateway Interface) is the legacy way of runing applications on the web from the mid 1990s or so. It was too inefficient for anything but small sites. CGI spawns a new process for every incoming request to execute a PHP script, a very resource intensive and inefficient way of doing things. No wonder it faded away over time as web applications became more complex.

FastCGI

FastCGI was introduced to avoid some of the issues with running languages, including PHP, inside the Apache process, as well as avoiding the inefficiency of CGI.

A FastCGI application is executed outside of the web server (Apache or other wise), and waits for requests from the web server using a socket. The web server and the FastCGI application can even be on separate physical machines and communicate over the network.

Because the web server adn the application processes are separate better isolation is possible.

In reality, running PHP as mod_fastcgi with Apache has proved to be problematic. Mainly with stability. Even on Drupal.org we tried it for a while, but switched back to mod_php after some time.

mod_fcgid

mod_fcgid was introduced to be binary compatible with FastCGI, but with better control over spawning processes. The benefits of process isolation are still there.

Installing fcgid

The article assumes you are using Ubuntu/Debian. For Red Hat or Centos, use the equivalent packages and yum to achieve the same results.

First we install the required Apache components, with Apache threaded server (MPM Worker), to save memory.

Then we enable the Apache fcgid module.

And install PHP CGI, and the a few other PHP components, if they are not already on your system.

Configuring fcgid

To configure fcgid, you have to do two things:

1. Create a new file in /etc/apache2/conf.d/php-fcgid.conf and put the following in it:

For a large site with a server with more memory and CPUs we can use this:

2. Add ExecCGI to the Options line in the vhosts you want to use PHP and or fcgid on, for example.

Now you should restart Apache, and fcgid should be active.

Memory consumption

The first thing you observe is that the memory size of the fcgi process is considerably larger (40MB) than when PHP is running as a mod_php within Apache (31MB). However, when using fcgi, Apache (pre-fork) is only 3.3 to 2.4 MB per process so you can have more of them to serve static files. The savings are even more if you use the threaded server. For example, an Apache process on a large site would be 20 to 25 MB, and the total number needed for thousands of threads would be 10 to 15 processes total. You also normally have less CGI processes in total than Apache.

For example:

Apache pre-fork
fcgi 15 processes * (40 MB – 21 MB shared) + 21 MB shared + (20 Apache procs * 6 MB) = 426 MB
mod_php 26 processes * (26 MB – 13 MB shared) + 13 MB shared = 351 MB

Apache threaded MPM Worker
fcgi 15 processes * (40 MB – 21 MB shared) + 21 MB shared + (10 Apache procs * 25 MB) = 290 MB
mod_php 26 processes * (26 MB – 13 MB shared) + 13 MB shared = 351 MB

The exact figures will vary for your site, depending on how you configured Apache and what modules you have enabled on your Drupal site.

Maximum number of processes

Setting the upper limit for the number php-cgi processes is possible but tricky. Normally MaxProcessCount should be the parameter to set to prevent creation of PHP processes above the number set for that parameter. I had to dig in the mod_fcgid source to find that parameter.

Make sure that you set this figure to a reasonable one. Setting it too low will cause an error to be logged in your web servers error log, for example:

[Sun Jul 25 17:06:23 2010] [notice] mod_fcgid: /home/example.com/www/index.php total process count 25 >= 25, skip the spawn request

On a 512MB VPS for example, a value of 7 to 10 seems to be adequate. For an 8GB dedicated server, a value of 45 or even higher will do. The exact figures will depend on how many modules you have, and how memory they consume.

Also, make sure that you do not set PHP_FCGI_CHILDREN at all. What happens is that fcgid uses it as a multiplier, not an upper maximum, and PHP will kept on breeding like rabbits, and the server will thrash and swap very quickly.

Performance benchmarking

We conducted performance benchmarks comparing mod_php and mod_fcgid. The conclusion is that mod_php is a bit faster than fcgid, but not by much.

Our benchmarks how the following at different concurrency levels:

Hunter Scott Newman  confirmed the benchmarks independently, and sent us the following results. Note that he is using the threded Apache server with fcgid.

Benefits and advantages

There are several advantages for using fcgid. Performance is not one of them, but the penalty may be well worth it for the following advantages:

  • Less memory consumption. Apache processes that serve static files are very small (3MB or less). So we can have more of those in memory.
  • Less network connections active, since there are less PHP process
  • Less database connections active, since there are less PHP processes. This is a very important point, since MySQL performance drops as the number of connections increase.

Case study: Large site with fcgid

In order to show what fcgid can help with, consider the following graphs. See the before and after comparison.

Memory usage by day, before and after.

Memory usage fcgid - day

The same was true over a week too.

Memory usage fcgid - by week

And the number of MySQL threads went down dramatically, because only PHP processes will connect to it, and not every Apache process.

fcgid MySQL threads

And also the number of network connections inside the server.

fcgid - Network connections

And just to make our lives easier, we wrote a monitoring script that will plot the number of php-cgi processes on a graph. We can know what is going on and what was going on too.

Munin php-cgi monitor

Caveats and precautions

Not everything is rosy though. There has to be some drawback.

APC still stores the op-code caches for Drupal and its modules. It has to do the parsing more often though, unlike on mod_php.

Because of that, you may on occasions see errors such as “Fatal error: Allowed memory size of nnnnnn bytes exhausted (tried to allocate nnnn bytes)”. Reloading the page causes it to load normally.

Although we have not dug too deep into it, we have found is that APC is not shared among the processes. And because the php-cgi processes are killed and new ones spawned, the persistence of APC’s user/data cache cannot be relied upon. This is not important for most users, but if you are using things like the Drupal cache router module or the performance logging module, this will impact you.

Conclusion

If pure speed is what you are after, then stay with mod_php.

However, for better resource usage and efficiency, consider moving to fcgid.

 

Fonte: https://2bits.com/articles/apache-fcgid-acceptable-performance-and-better-resource-utilization.html

Facebook Comments