Return-Path: Delivered-To: new-httpd-archive@hyperreal.org Received: (qmail 25047 invoked by uid 6000); 3 Nov 1999 21:51:23 -0000 Received: (qmail 24670 invoked from network); 3 Nov 1999 21:51:11 -0000 Received: from sgi.sgi.com (HELO sgi.com) (192.48.153.1) by taz.hyperreal.org with SMTP; 3 Nov 1999 21:51:11 -0000 Received: from cthulhu.engr.sgi.com (cthulhu.engr.sgi.com [192.26.80.2]) by sgi.com (980305.SGI.8.8.8-aspam-6.2/980304.SGI-aspam: SGI does not authorize the use of its proprietary systems or networks for unsolicited or bulk email from the Internet.) via ESMTP id QAA8566238 for <@external-mail-relay.sgi.com:new-httpd@apache.org>; Wed, 3 Nov 1999 16:51:04 -0500 (EST) mail_from (mja@trudge.engr.sgi.com) Received: from trudge.engr.sgi.com (trudge.engr.sgi.com [198.29.115.101]) by cthulhu.engr.sgi.com (980427.SGI.8.8.8/970903.SGI.AUTOCF) via ESMTP id NAA96928 for <@cthulhu.engr.sgi.com:new-httpd@apache.org>; Wed, 3 Nov 1999 13:51:02 -0800 (PST) mail_from (mja@trudge.engr.sgi.com) Received: (from mja@localhost) by trudge.engr.sgi.com (980427.SGI.8.8.8/970903.SGI.AUTOCF) id NAA48106 for new-httpd@apache.org; Wed, 3 Nov 1999 13:51:01 -0800 (PST) From: mja@trudge.engr.sgi.com (Mike Abbott) Message-Id: <199911032151.NAA48106@trudge.engr.sgi.com> Subject: [PATCH] 10x performance increase patch #9 To: new-httpd@apache.org Date: Wed, 3 Nov 1999 13:51:01 -0800 (PST) X-Mailer: ELM [version 2.4 PL23] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org Apache Developers, Here is my ninth of ten patches for increasing Apache's performance. This one includes miscellaneous performance tweaks, a new command line option to facilitate debugging, and a guide to achieving Apache's best performance on the SPECweb96 benchmark. It also gives credit to my employer and myself, as stipulated in my introduction to these patches. The base for this patch is Apache/1.3.6 + 10x performance increase patches #1 through #8. After I contribute the final patch I'll port all my patches to the latest Apache release. Note that this patch includes two new files, htdocs/manual/misc/perf-mja.html and htdocs/sgi_performance.gif.uu. The latter must be uudecoded to create the new file htdocs/sgi_performance.gif. When I apply the patch to a pure 1.3.6 tree my version of the patch command puts these files in the current directory rather than where they belong. I hope yours works! As always, I welcome your review, questions, and feedback. -- Michael J. Abbott mja@sgi.com http://reality.sgi.com/mja ======================================================================== diff -Naur apache_1.3.6+01-08/ABOUT_APACHE apache_1.3.6+01-09/ABOUT_APACHE --- apache_1.3.6+01-08/ABOUT_APACHE Sat Feb 13 18:30:47 1999 +++ apache_1.3.6+01-09/ABOUT_APACHE Wed Oct 20 16:39:42 1999 @@ -104,7 +104,8 @@ Other major contributors - Howard Fear (mod_include), Florent Guillaume (language negotiation), + Mike Abbott (performance), Howard Fear (mod_include), + Florent Guillaume (language negotiation), Koen Holtman (rewrite of mod_negotiation), Kevin Hughes (creator of all those nifty icons), Rasmus Lerdorf (mod_info, mod_php, mod_php3), diff -Naur apache_1.3.6+01-08/conf/httpd.conf-dist apache_1.3.6+01-09/conf/httpd.conf-dist --- apache_1.3.6+01-08/conf/httpd.conf-dist Thu Sep 2 10:12:04 1999 +++ apache_1.3.6+01-09/conf/httpd.conf-dist Wed Oct 20 16:39:51 1999 @@ -160,7 +160,7 @@ # isn't really needed, but a few (such as Solaris) do have notable leaks # in the libraries. # -MaxRequestsPerChild 30 +MaxRequestsPerChild 0 # # Listen: Allows you to bind Apache to specific IP addresses and/or diff -Naur apache_1.3.6+01-08/htdocs/index.html apache_1.3.6+01-09/htdocs/index.html --- apache_1.3.6+01-08/htdocs/index.html Wed May 20 07:59:42 1998 +++ apache_1.3.6+01-09/htdocs/index.html Wed Oct 20 16:40:02 1999 @@ -47,5 +47,9 @@
+
+
+ +
diff -Naur apache_1.3.6+01-08/htdocs/manual/invoking.html apache_1.3.6+01-09/htdocs/manual/invoking.html --- apache_1.3.6+01-08/htdocs/manual/invoking.html Mon Mar 22 16:17:34 1999 +++ apache_1.3.6+01-09/htdocs/manual/invoking.html Wed Oct 20 16:40:18 1999 @@ -129,6 +129,10 @@
Windows only: signal Apache to restart or shutdown. option is one of "shutdown" or "restart". (Apache 1.3.3 and later). +
-i +
For testing: Do not daemonize (i.e., do not fork and exit on startup). +(Apache 1.3.X and later.) +
-?
Print a list of the httpd options, and then exit (up to Apache 1.3.3. Later version use -h instead). diff -Naur apache_1.3.6+01-08/htdocs/manual/misc/perf-mja.html apache_1.3.6+01-09/htdocs/manual/misc/perf-mja.html --- apache_1.3.6+01-08/htdocs/manual/misc/perf-mja.html +++ apache_1.3.6+01-09/htdocs/manual/misc/perf-mja.html Wed Nov 3 10:28:37 1999 @@ -0,0 +1,409 @@ + + + + + Making Apache Ten Times Faster + + + +

+

[APACHE DOCUMENTATION]

+

+Apache HTTP Server Version 1.3

+

+

+

+Making Apache Ten Times Faster

+

+Mike Abbott - mja@sgi.com

+

+

+I have contributed ten patches to +the Apache Project that together increase the performance of the Apache +HTTP server up to 900%. This document summarizes how to maximize the +performance of Apache using my patches. The measure of performance in +this document is the SPECweb96 +benchmark, which measures only the number of static HTTP/1.0 GET +requests a web server can service per second. This paper assumes a +working knowledge of Apache internals.

+
+The advice that follows may or may not apply to your system and may +increase or decrease your system's performance depending on factors +beyond the scope of this document. Use this guide only in conjunction +with a clear understanding of your performance goals and overriding +needs.
+

+Contents

+ +

+Introduction

+

+The patches + I contributed to the Apache Project modify Apache's source code and +standard configuration files to speed up the processing of HTTP +requests in various ways. Still, Apache must be configured, compiled, +and tuned to achieve the best performance on a given system. The +following sections describe the configurable options relevant for high +performance.

+

+The options fall into three categories: those that control the QSC, +those that control Apache's child processes, and those that control +other things.

+

+Tuning the QSC

+

+The Quick Shortcut Cache (QSC) cuts out +unnecessary processing for requests to cached static content. It sports +a number of configurable options. +Two of these, QSC_HASH_SIZE and QSC_MAX_SIZE, +limit the maximum size of the cache and almost certainly need to be +increased from their default values to provide the maximum benefit for +a given system. A third, QSC_HEADER_GRAIN (which normally +uses the same value as CACHE_ALIGNMENT), regulates +alignment and padding and can improve performance more than you might +think when set correctly. See the QSC +documentation for details on these +options and for instructions on using +the QSC.

+

+Also, the QSC can manage the very large amounts of data enabled by a 64-bit address space although with a slight +performance penalty.

+

+As patched, Apache's standard run-time configuration file httpd.conf + enables the QSC when the mmap_static module is installed. Leave the QSC +on directive as is.

+

+Summary of options in this section:

+ +

+Tuning Child Processes

+

+Under heavy load, a system can spend most of its computing power +creating, destroying, and scheduling Apache +child processes. Eliminating all this overhead allows the system to +spend more of its time processing HTTP requests but reduces Apache's +ability to adapt to a changing load.

+

+As patched, Apache's standard run-time configuration file httpd.conf + removes the limit on the number of requests each child process handles +before terminating itself and forcing the parent Apache process to fork +a replacement. Leave the MaxRequestsPerChild + 0 directive as is.

+

+Choose a number of processes and force Apache always to use that +number, never more or less. Set the MinSpareServers, MaxSpareServers, StartServers, +and MaxClients + options all to the same value and ignore the resulting warning:

+
+server reached MaxClients setting, consider raising the +MaxClients setting
+

+The number you use is up to you but remember, sometimes having fewer +processes runs faster than having more. Start with, say, two per +network interface and increase from there as necessary.

+

+Bind interrupts from network interface devices to specific processors +(distributing them as evenly as possible across all the processors) and +bind the Apache child processes listening to those interfaces to the +same processors using the Listen + directive. Force each child process to listen only to its designated +interface -- and eliminate performance-sapping accept serialization + -- by turning SingleListen + on.

+

+Summary of options in this section:

+ +

+General Tuning

+

+Always compile optimized.

+

+Define SPEED_DAEMON which defines all of these other +tokens:

+ +

+Define the value of LOG_BUFSIZE + to be some multiple of the system's page size, less a few dozen bytes +or so for overhead.

+

+Use only the Common Log Format.

+

+Raise the limit on the number of response bytes written at a time by +defining the value of MMAP_SEGMENT_SIZE to be larger than +the largest cached file -- but not on Linux, where this actually slows +things down!

+

+Make the listen queue size as large as possible using the ListenBacklog + directive.

+

+Summary of options in this section:

+ +

+Example

+

+Here is the configuration I use to achieve maximum SPECweb96 +performance on an SGI Origin200 server running Irix 6.5 with two +processors, two gigabytes of memory, and four 100BaseT network +interfaces. Without any patching or tuning Apache on this system +handles 240 operations per second; with my patches and the following +tuning it handles 2400*.

+
+* These are actual SPECweb96 results and while I believe they are +accurate and meaningful, they have not been submitted to SPEC for +review or publication. The following is for illustrative purposes only +and is not a SPECweb96 disclosure.
+ +

+See also

+ +
+

+Apache HTTP Server Version 1.3

+

+Index

+ + diff -Naur apache_1.3.6+01-08/htdocs/manual/misc/perf-tuning.html apache_1.3.6+01-09/htdocs/manual/misc/perf-tuning.html --- apache_1.3.6+01-08/htdocs/manual/misc/perf-tuning.html Tue Jul 20 22:24:35 1999 +++ apache_1.3.6+01-09/htdocs/manual/misc/perf-tuning.html Wed Nov 3 10:28:37 1999 @@ -39,6 +39,13 @@ performance out of Apache's current model, and want to understand why it does some things which slow it down. +

Mike Abbott from SGI has increased Apache's performance ten-fold for +static HTTP GET requests such as those issued by the SPECweb96 benchmark. See +his tuning document and SGI's Web Server Performance Tuning +Guide for more information. +

Note that this is tailored towards Apache 1.3 on Unix. Some of it applies to Apache on NT. Apache on NT has not been tuned for performance yet, in fact it probably performs very poorly because NT performance requires diff -Naur apache_1.3.6+01-08/htdocs/manual/misc/perf.html apache_1.3.6+01-09/htdocs/manual/misc/perf.html --- apache_1.3.6+01-08/htdocs/manual/misc/perf.html Mon Mar 22 16:17:45 1999 +++ apache_1.3.6+01-09/htdocs/manual/misc/perf.html Wed Nov 3 10:28:37 1999 @@ -33,6 +33,7 @@

  • BSD-based (BSDI, FreeBSD, etc)
  • Digital UNIX
  • HPUX +
  • SGI IRIX
  • Linux
  • Solaris
  • SunOS 4.x @@ -73,6 +74,15 @@
  • We have some newsgroup postings on how to tune Digital UNIX 3.2 and 4.0. + +


    +

    +IRIX +

    + +See Mike Abbott's performance tuning +document and SGI's Web Server +Performance Tuning Guide.


    diff -Naur apache_1.3.6+01-08/htdocs/manual/mod/mod_mmap_static.html apache_1.3.6+01-09/htdocs/manual/mod/mod_mmap_static.html --- apache_1.3.6+01-08/htdocs/manual/mod/mod_mmap_static.html Thu Sep 2 11:40:28 1999 +++ apache_1.3.6+01-09/htdocs/manual/mod/mod_mmap_static.html Wed Oct 20 16:41:09 1999 @@ -64,6 +64,10 @@ is that this check would need an extra stat() every time which is a waste and against the intent of I/O reduction.

    +

    + Note that mapping a large number of files greatly increases server + start-up and restart time. +

    Directives

      diff -Naur apache_1.3.6+01-08/htdocs/sgi_performance.gif.uu apache_1.3.6+01-09/htdocs/sgi_performance.gif.uu --- apache_1.3.6+01-08/htdocs/sgi_performance.gif.uu +++ apache_1.3.6+01-09/htdocs/sgi_performance.gif.uu Wed Nov 3 13:36:08 1999 @@ -0,0 +1,46 @@ +begin 444 sgi_performance.gif +M1TE&.#EA!0%'`,3_``"O3A"T62"Y9#"^;T##>E#(AFG0EW_7IH_ +M:*JN;.N^<"S/=&W?>*[O?.__P*!P2"P:C\BD$PNF\_HM'K-;KO?\+A\3J_;[_B\7@N93"![@6D0%AT=%8""BET/)1,: +MAAH3BY17#Q(5%A6-(A,8AAB3E:-1$16&'1H4)!09&:NDL4T2%Z@:%Q(E$8FR +MO3,/$+LO$,&U'1L6%+R^S#1]%)D5%!++)9?0F9$5NA+=W1$-EQ(1#^#-YPVF +MJ+85YKH5D.L=&,L0%1D8^1D6NQ7^$Q;0-8M0"!6'=?QT%31T,%)"$03E8@SLB*<-)"P%'.ZFN\#&F$9! +M`&"J'`4`KB:I>S>OC0@9.G"XR9"243^#5 +M2^-!063*4DS(C%)TP0RE$Z.&HIKUX\A*8IN8?6-"PPX +M>.Z-$&`*"S`V@/\"QC%(0H+]'2"@"><5F!Z!RI4P6W<)N+>`<2,@4)\)%,3# +MT#XY=<);:"6,!IQ:PM5@0``"U`5``/^)4("-`"`@P@(T\N@`9#P.T,`"-=:% +MXP@#)%G75`G`9:-4/+Z&I(T!C-AD`%..V(!J-OJ8'I=U#6"A"&#:*%>&Q8FP +M99PW4&.D!E!ZI)*8%R"5GI`8HF8"HCC4P +MP`$*["C`CTJR%VL`(UBJ0`*:BL`EKK'^.4*"G3K8`)NKJ7JCKS<&VRG_IL4V +MD*P"#B1Y9Z231INJ"+&*B4($$U1@3"0Y16!49Q'$PGKT8.HQ$'.0EFR`874#"!4@UAT-G0-4"M=%T'))YLRTRC +M;9SA4I,=]6M<*[>``59EJ[;7;W=-0.('U`AB_]E2,]YTR52OG9?B;9=^=LQQ +M2\VE"'B9ZP)UAY``CRT9F"B)"833`#G2>$K=^<##HTGUT8Y#K'*4>*(.HNJR +M%;]\U:Z3K/STG!=_E=N-PXV]9+$*^#$*`*78B4>%BK"0/$"9A52,PGL]N>DG +M'.]T\E>78'7E*N/2?[:6NNY5CS8J`-_IMB>^UY'N3YWK6NPD\R\&-.P$%M`` +M!P3GB)_P1&\HN0`D4%2-^8&":##@7P3U]SC[*4UR_Z,:96(HO09V#FH)S![3 +M",@]O71.@0<OTL7*,3LR5P(` +M%K[^1:UNVI(9#$L'0/]5[<02QJM$<1X`9AF#`'Q;@#4K,89N/1%$%%#"(O5Z` +METX=8$>`9%AC#J":,[X-2,!"VZU`29XQ4DZ&*GM+`100J\@54"]`&J5J4EG* +M`\SH82?@4JV(9`!4U44R:Q1E,4M)KAOY4DTH4,TJ;^0>Z)T1?2:"7U`,Q1L* +M1.";X"SASWJ&BH>D4$IU$8"7%.`D`I`G`*DLP9*:ELX1[6B.5HO5B.")MB<- +M@)=4BU*.KG1,]]1R6BD@5AH-1"8<$>",7!-HU=II4"P1JU8FD!-L4`8!Z@D90P]K(M(.SO&&D,Q&+VLR>0 +M`&^"THUTL0NTJ#V!1E*ACW)V)K6HI:PD;6&!L,(6M>FR@&XUD9O;^O:WP`VN +K<(=+W.(:][C(3:YRE\OZ"MC-KG:WRUT1A```.PVN +` +end diff -Naur apache_1.3.6+01-08/src/main/http_main.c apache_1.3.6+01-09/src/main/http_main.c --- apache_1.3.6+01-08/src/main/http_main.c Thu Sep 2 10:18:50 1999 +++ apache_1.3.6+01-09/src/main/http_main.c Wed Oct 20 16:42:16 1999 @@ -985,7 +985,7 @@ fprintf(stderr, "Usage: %s [-d directory] [-f file]\n", bin); #endif fprintf(stderr, " %s [-C \"directive\"] [-c \"directive\"]\n", pad); - fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t]\n", pad); + fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-i]\n", pad); fprintf(stderr, "Options:\n"); #ifdef SHARED_CORE fprintf(stderr, " -R directory : specify an alternate location for shared object files\n"); @@ -1006,6 +1006,7 @@ fprintf(stderr, " -k shutdown : tell running Apache to shutdown\n"); fprintf(stderr, " -k restart : tell running Apache to do a graceful restart\n"); #endif + fprintf(stderr, " -i : do not daemonize\n"); exit(1); } @@ -2933,6 +2934,8 @@ * Here follows a long bunch of generic server bookkeeping stuff... */ +int daemonize = 1; + static void detach(void) { #if !defined(WIN32) @@ -2942,12 +2945,14 @@ #if !defined(MPE) && !defined(OS2) && !defined(TPF) /* Don't detach for MPE because child processes can't survive the death of the parent. */ - if ((x = fork()) > 0) - exit(0); - else if (x == -1) { - perror("fork"); - fprintf(stderr, "%s: unable to fork new process\n", ap_server_argv0); - exit(1); + if (daemonize) { + if ((x = fork()) > 0) + exit(0); + else if (x == -1) { + perror("fork"); + fprintf(stderr, "%s: unable to fork new process\n", ap_server_argv0); + exit(1); + } } RAISE_SIGSTOP(DETACH); #endif @@ -2977,24 +2982,26 @@ } #endif - /* close out the standard file descriptors */ - if (freopen("/dev/null", "r", stdin) == NULL) { - fprintf(stderr, "%s: unable to replace stdin with /dev/null: %s\n", - ap_server_argv0, strerror(errno)); - /* continue anyhow -- note we can't close out descriptor 0 because we - * have nothing to replace it with, and if we didn't have a descriptor - * 0 the next file would be created with that value ... leading to - * havoc. + if (daemonize) { + /* close out the standard file descriptors */ + if (freopen("/dev/null", "r", stdin) == NULL) { + fprintf(stderr, "%s: unable to replace stdin with /dev/null: %s\n", + ap_server_argv0, strerror(errno)); + /* continue anyhow -- note we can't close out descriptor 0 because we + * have nothing to replace it with, and if we didn't have a descriptor + * 0 the next file would be created with that value ... leading to + * havoc. + */ + } + if (freopen("/dev/null", "w", stdout) == NULL) { + fprintf(stderr, "%s: unable to replace stdout with /dev/null: %s\n", + ap_server_argv0, strerror(errno)); + } + /* stderr is a tricky one, we really want it to be the error_log, + * but we haven't opened that yet. So leave it alone for now and it'll + * be reopened moments later. */ } - if (freopen("/dev/null", "w", stdout) == NULL) { - fprintf(stderr, "%s: unable to replace stdout with /dev/null: %s\n", - ap_server_argv0, strerror(errno)); - } - /* stderr is a tricky one, we really want it to be the error_log, - * but we haven't opened that yet. So leave it alone for now and it'll - * be reopened moments later. - */ #endif /* ndef WIN32 */ } @@ -4713,7 +4720,7 @@ #ifndef TPF while ((c = getopt(argc, argv, - "D:C:c:Xd:f:vVlLR:Sth" + "D:C:c:Xd:f:vVlLR:Sthi" #ifdef DEBUG_SIGSTOP "Z:" #endif @@ -4742,6 +4749,7 @@ ap_set_version(); printf("Server version: %s\n", ap_get_server_version()); printf("Server built: %s\n", ap_get_server_built()); + printf("Performance Tuned by SGI \n"); exit(0); case 'V': ap_set_version(); @@ -4778,6 +4786,9 @@ break; case 'h': usage(argv[0]); + case 'i': + daemonize = 0; + break; case '?': usage(argv[0]); } diff -Naur apache_1.3.6+01-08/src/modules/experimental/mod_mmap_static.c apache_1.3.6+01-09/src/modules/experimental/mod_mmap_static.c --- apache_1.3.6+01-08/src/modules/experimental/mod_mmap_static.c Thu Sep 2 10:37:38 1999 +++ apache_1.3.6+01-09/src/modules/experimental/mod_mmap_static.c Wed Oct 20 16:51:19 1999 @@ -129,6 +129,7 @@ void *mm; struct stat finfo; char mtimestr[32]; + char sizestr[21]; /* big enough to hold any 64-bit file size + null */ } a_file; typedef struct { @@ -208,6 +209,7 @@ tmp.filename = ap_pstrdup(cmd->pool, filename); ap_gm_timestr_822_buf(tmp.mtimestr, sizeof tmp.mtimestr, tmp.finfo.st_mtime); + ap_snprintf(tmp.sizestr, sizeof tmp.sizestr, "%ld", (long) tmp.finfo.st_size); sconf = ap_get_module_config(cmd->server->module_config, &mmap_static_module); new_file = ap_push_array(sconf->files); *new_file = tmp; @@ -368,10 +370,18 @@ } ap_set_etag(r); - if (((errstatus = ap_meets_conditions(r)) != OK) - || (errstatus = ap_set_content_length (r, (ap_int32) match->finfo.st_size))) { - return errstatus; - } + + if ((errstatus = ap_meets_conditions(r)) != OK) + return errstatus; + + /* + * ap_set_content_length() always converts the same number and never + * returns an error. Accelerate it. + * if ((errstatus = ap_set_content_length (r, (ap_int32) match->finfo.st_size))) + * return errstatus; + */ + r->clength = (ap_int32) match->finfo.st_size; + ap_table_setn(r->headers_out, "Content-Length", match->sizestr); rangestatus = ap_set_byterange(r);