> I don't completely understand you comment, but you are quite right that anytime the
> scoreboard needs to be walked, locking will be required. The scoreboard will -not- 
>need to
> be walked except in these relatively rare cases:
>
> 1. During a graceful restart (manipulates elements in the scoreboard)
> 2. During MaxRequestPerChild triggered child shutdown (manipulates elements in the
> scoreboard)
> 3. Processing a mod_status request (walks the scoreboard)
> 4. Processing an SNMP request (walks the scoreboard)
>
> Requests that do not require a scoreboard walk or adding/deleting entries from the
> scoreboard (which is 99.999% or more of all requests; all requests except the ones 
>above)
> will not require locking at all.  Let me restate this... mainline requests will NOT 
>be
> required to make any lock calls at all. Ever.  Mainline requests can be served and 
>their
> status tracked even when the scoreboard is locked, so this design does not suffer 
>-any-
> performance penalties in the mainline case caused by locking.

You are looking at this from a Web server point of view.  Don't.  Look at
this from an ops point of view.  How often is a large site going to query
the current connections or child status (for example) using SNMP?  Both of
those require a walk of the scoreboard.  If you ask for them once a
minute, you are going to seriously hinder the performance of your server.
The problem gets worse as the number of threads increases.  How many other
SNMP requests carry the same penalty?

BTW, there are a few more that modules that make use of the scoreboard
information:

5.  Whenever Apache::Scoreboard walks the scoreboard (this has been used
by perl modules to download the scoreboard once every 15 seconds to
generate graphs on another machine.)
6.  Whenever Apache::VMonitor walks the scoreboard  (Another graphicl
monitor of configurable refresh rate.
7.  Whenever any other management module walks the scoreboard.

You can't guarantee how often a third party module will walk the
scoreboard, because you don't know everything about every third part
module.  Since you don't know how often it will be walked, you don't know
how often the mutex will be locked.

> The only reason we have locking at all is to prevent the 4 cases listed above from
> colliding with each other.  Even in the 4 cases above, the lock contention will be 
>minimal
> and the performance degradation minimal and perhaps not even measureable.
>
> A few other benefits to Pauls design:
> 1. Eliminates the requirement for compiled in HARD_SERVER_LIMIT or HARD_THREAD_LIMIT.

You still need to request a certain amount of shared memory when you
start the parent process, and you will require HARD_SERVER_LIMIT and
HARD_THREAD_LIMIT to know how much to request.  Either that, or whenever
you add a new child, you will need to allocate more shared memory, and
somehow tell your child processes about it.

> 2. You don't need to allocate child score if you don't care about mod_status (but it 
>can
> be added during a restart)

You still need to request a certain amount of shared memory when you
start the parent process, and you will require HARD_SERVER_LIMIT and
HARD_THREAD_LIMIT to know how much to request.  Either that, or whenever
you restart, you will forget all information about your child processes.

> 3. If you choose to not enable mod_status, you will likely see a nice performance 
>boost on
> multi CPU machines because we are not invalidating a CPUs cache each time we touch a
> worker score entry (which is on every request).

This can be implemented just as well with the table implementation.  The
only thing you have to do is pad the scoreboard entry size to make it
equal to one cache line.

> 4. Does not require any changes to the MPM.  Each MPM can start threads according to 
>its'
> ThreadsPerChild setting w/o needing to pay attention to the scoreboard (I believe 
>your
> design required child processes to wait for worker score slots to become available 
>before
> it can start threads. This is imposing too much unnecessary work on the MPM.).

You are ignoring one problem with the design.  I have now posted about it
three times, and nobody has told me how it will be fixed.  You need to
honor MaxClients.  If I set MaxClients to 250, then I expect MaxClients to
be 250, regardless of whether those clients are long-lived or not.  If
every child can always start threads according to ThreadsPerChild, you
will be violating MaxClients on a heavily loaded server.  This means that
you are actually requiring MORE changes to the starting logic than the
table implementation, because each child, will need to determine how many
threads to start at any given time.

Ryan

_______________________________________________________________________________
Ryan Bloom                              [EMAIL PROTECTED]
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Reply via email to