Project

General

Profile

Actions

Docs PerformanceFastCGI » History » Revision 2

« Previous | Revision 2/31 (diff) | Next »
jan, 2006-09-19 23:00


{{{
#!rst ==============================
Optimizing FastCGI performance ==============================

.. contents::

Overview ========

If you lately ran into the questions

  • "How many PHP backends do I need for my load" or
  • "Why is my application returning the error 500 from time to time"

you want to read this article very carefully.

Measuring the load ==================

Load the status-module and enable the statistics: ::

server.modules = {..., "mod_status", ... }
status.statistics-url = "/server-counters"

The counters page lists serveral counters of the fastcgi module:

  • the over all number of requests handle by the module
  • currently waiting requests
  • currently waiting request per backend

.. note::

If you have more than one backend you should name each backend individually. ::
fastcgi.server = ( 
".php" => (
"backend1" => ( "host" => "php-srv1", ... ),
"backend2" => ( "host" => "php-srv2", ... ),
)
)

You might this output: ::

fastcgi.active-requests: 22
fastcgi.backend.0.0.connected: 5639
fastcgi.backend.0.0.died: 0
fastcgi.backend.0.0.disabled: 0
fastcgi.backend.0.0.load: 11
fastcgi.backend.0.0.overloaded: 0
fastcgi.backend.0.1.connected: 7724
fastcgi.backend.0.1.died: 0
fastcgi.backend.0.1.disabled: 0
fastcgi.backend.0.1.load: 11
fastcgi.backend.0.1.overloaded: 0
fastcgi.backend.0.load: 22
fastcgi.requests: 13363

We have 2 backends (max-procs = 2) and a current load of 22 (fastcgi.backend.0.load: 22). The load is equally
distributed over the two backends (fastcgi.backend.0.0.load: 11, fastcgi.backend.0.1.load: 11).

How many php-process do I need ? ================================

That's the question why you are here I think and to answer it let me create a small example:

lighty is managing a pipe. On one side are your users with their webbrowsers, on the other side is PHP. In case
you have more incomming requests than your backends can handle, lighty will queue them up and will push the new
requests to the backends when they are free again. If the queue still fills up, it will burst and the next
requests to this backend will be denied. You will see a message in the errorlog like ::

... load = 380 ...

To come up with a formula to calculate the number of backends you need think of:

  • you have 100 php-req/s
  • the average request-time on PHP side is 0.1s

In the average case you need: ::

100 php-reqs/s * 0.1s/php-req = 10 php-procs

You see ? As you propably can't control the number of incoming PHP-requests, you can only tune the average
request time spent in the PHP process.

Can I have too many php-processes =================================

Having too many PHP processes can be bad too. If you have more than you need, the PHP processes will eat all the memory
and will hit the swap-space.

If you are using a config like: ::

fastcgi.server = ( ".php" =>
(( "socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/bin/php-cgi",
"max-procs" => 10,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "16",
"PHP_FCGI_MAX_REQUESTS" => "1000"
),
"broken-scriptfilename" => "enable"
))
)

you will have (following the famous formular)::

num-procs = max-procs * ( 1 + PHP_FCGI_CHILDREN )
10 * (16 + 1) = 170 procs

Together with a PHP 5.1.5 running APC 3.0.11 a single PHP process takes about 13Mb (RSZ) for itself: ::

$ ps axu | grep php
400 web 16 0 152m 13m 6804 S 1 0.7 0:01.99 php-fcgi
13M * 160 = 2Gb RAM

Not all of them will be using 13m from the start, but you see the problem I think.

}}}

Updated by jan about 18 years ago · 2 revisions