httpd-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nadav Har'El <...@math.technion.ac.il>
Subject Re: [users@httpd] mod-cgi reads entire output into memory...
Date Tue, 17 Jul 2012 04:50:53 GMT
On Mon, Jul 16, 2012, Nick Kew wrote about "Re: [users@httpd] mod-cgi reads entire output into
memory...":
> On Mon, 16 Jul 2012 17:07:23 +0300
> Nadav Har'El <nyh@math.technion.ac.il> wrote:
> > I looked at the httpd code, discovered (if I understand correctly) that
> > 1. As I already guessed, Apache doesn't let the CGI write directly to the
> > socket, but rather asks it to write to a pipe, which Apache then reads.
> 
> Yep.  That's what CGI is all about.

:-)

I've set out to write a simple mod_cgi replacement which lets the child
process write its output directly to the client socket - it behaves like
NPH (no possibility for Apache to fix the CGI's headers or to filter its
output) but I think it will be useful in a lot of cases (who filters
CGI output anyway?) - and certainly more efficient in mine. In fact
I wonder why it shouldn't always work like that with NPH.

I "almost" have such code, but ran into a mystery - where in the
request_req can I find the client socket, so I can write to it directly?
There are so many layers of output filters, APR, etc., that I can't seem
to find this simple thing...

> > 2. When Apache reads this data from the pipe, it doesn't write it directly
> > but rather just adds it to a "bucket brigade" which collects more and
> > more data.
> 
> No, it doesn't collect more and more data, unless some filter needs to
> buffer the entire output.  Normally it passes data down the chain.
> Each filter's job is to process a chunk of data then pass it to the next.

In my tests definitely all the data was being collected, and I was not
using any output filter (at least not that I know of) - not using
deflate or anything of that sort.

I'm no longer sure about my original statement that the buffering happens
when the client reads the output slowly. In fact, it now looks to me
that extreme memory use actually happens when the client reads very
very quickly (i.e., the client is through localhost). I haven't got a
clue why this is happening - I don't suppose Apache has any time-based
bucket-brigade flow control or memory pool reuse algorithms?

> > I confirmed that this is indeed a flow-control problem by changing the
> > CGI to sleep for 1 second after outputting each 64 MB (i.e., 8 batches
> > of 64 MB output); Now, the memory usage was around 64 MB, not 512 MB,
> > because Apache had the time to output each batch and free its memory
> > before the next batch came.
> 
> Sounds like the entire contents of the pipe got read into memory in
> a single read!  Not good, but not as bad as you think.

Is this actually possible? Doesn't Apache allocate a relatively small
buffer and read into that? How can it read 512 MB in a single read?

> Sleeping is a drastic workaround.  What happens if you just flush your
> CGI output every 8Mb (or, preferably, in smaller chunks than that)?

The CGI is a trivial one written in C, using stdio and puts()'ing 8192
strings of 65536 bytes each. I don't think that stdio buffers 512 MB
or anything close to that. Also like I said, the CGI program itself does
NOT grow in memory use - just Apache.

> You might want to look at the mod_proxy framework as an alternative harness
> to run your program.

Interesting idea. I'll take a look at that.

Thanks,
Nadav.

-- 
Nadav Har'El                        |     Tuesday, Jul 17 2012, 27 Tammuz 5772
nyh@math.technion.ac.il             |-----------------------------------------
Phone +972-523-790466, ICQ 13349191 |Despite the cost of living, have you
http://nadav.harel.org.il           |noticed how it remains so popular?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Mime
View raw message