Apache Performance Tuning
DeveloperSide.NET Articles [펌] http://www.devside.net/articles/apache-performance-tuning
Forewarning:
"Premature optimization is the root of all evil." -- Donald Knuth.
...in other words, don't implement in extra complexity if you don't need it. A site handling a few thousand requests per day will do fine on a default configuration and just about any hardware. This article is geared towards a site that needs to handle multiple concurrent requests [ten to several hundred per second].
General [in order of importance]
RAM
The single biggest issue affecting webserver performance is RAM. Have as much RAM as your hardware, OS, and funds allow [within reason].
The more RAM your system has, the more processes [and threads] Apache can allocate and use; which directly translates into the amount of concurrent requests/clients Apache can serve.
Generally speaking, disk I/O is usually a close 2nd, followed by CPU speed and network link. Note that a single PII 400 Mhz with 128-256 Megs of RAM can saturate a T3 (45 Mbps) line.
Select MPM
Chose the right MPM for the right job:
prefork [default MPM for Apache 2.0 and 1.3]:
- Apache 1.3-based.
- Multiple processes, 1 thread per process, processes handle requests.
- Used for security and stability.
- Has higher memory consumption and lower performance over the newer Apache 2.0-based threaded MPMs.
worker:
- Apache 2.0-based.
- Multiple processes, many threads per process, threads handle requests.
- Used for lower memory consumption and higher performance.
- Does not provide the same level of isolation request-to-request, as a process-based MPM does.
winnt:
- The only MPM choice under Windows.
- 1 parent process, exactly 1 child process with many threads, threads handle requests.
- Best solution under Windows, as on this platform, threads are always "cheaper" to use over processes.
Configure MPM
Core Features and Multi-Processing ModulesDefault Configuration
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
MaxClients 150
MaxRequestsPerChild 1000
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
<IfModule mpm_winnt.c>
ThreadsPerChild 250
MaxRequestsPerChild 0
</IfModule>
Directives
MaxClients, for prefork MPM
MaxClients sets a limit on the number of simultaneous connections/requests that will be served.
I consider this directive to be the critical factor to a well functioning server. Set this number too low and resources will go to waste. Set this number too high and an influx of connections will bring the server to a stand still. Set this number just right and your server will fully utilize the available resources.
An approximation of this number should be derived by dividing the amount of system memory (physical RAM) available by the maximum size of an apache/httpd process; with a generous amount spared for all other processes.
MaxClients ≈ (RAM - size_all_other_processes)/(size_apache_process)Use 'ps -ylC httpd --sort:rss' to find process size. Divide number by 1024 to get megabytes. Also try 'top'.
Use 'free -m' for a general overview. The key figure to look at is the buffers/cache used value.
Use 'vmstat 2 5' to display the number of runnable, blocked, and waiting processes; and swap in and swap out.
Example:
- System: VPS (Virtual Private Server), CentOS 4.4, with 128MB RAM
- Apache: v2.0, mpm_prefork, mod_php, mod_rewrite, mod_ssl, and other modules
- Other Services: MySQL, Bind, SendMail
- Reported System Memory: 120MB
- Reported httpd process size: 7-13MB
- Assumed memory available to Apache: 90MB
Optimal settings:
- StartServers 5
- MinSpareServers 5
- MaxSpareServers 10
- ServerLimit 15
- MaxClients 15
- MaxRequestsPerChild 2000
With the above configuration, we start with 5-10 processes and set a top limit of 15. Anything above this number will cause serious swapping and thrashing under a load; due to the low amount of RAM available to the [virtual] Server. With a dedicated Server, the default values [ServerLimit 256] will work with 1-2GB of RAM.
When calculating MaxClients, take into consideration that the reported size of a process and the effective size are two different values. In this setup, it might be safe to use 20 or more workers... Play with different values and check your system stats.
Note that when more connections are attempted than there are workers, the connections are placed into a queue. The default queue size value is 511 and can be adjusted with the ListenBackLog directive.
ThreadsPerChild, for winnt MPM
On the Windows side, the only useful directive is ThreadsPerChild, which is usually set to a value of 250 [defaults to 64 without a value]. If you expect more, or less, concurrent connections/requests, set this directive appropriately. Check process size with Task Manager, under different values and server load.
MaxRequestsPerChild
Directive MaxRequestsPerChild is used to recycle processes. When this directive is set to 0, an unlimited amount of requests are allowed per process.
While some might argue that this increases server performance by not burdening Apache with having to destroy and create new processes, there is the other side to the argument...
Setting this value to the amount of requests that a website generates per day, divided by the number of processes, will have the benefit of keeping memory leaks and process bloat to a minimum [both of which are a common problem]. The goal here is to recycle each process once per day, as apache threads gradually increase their memory allocation as they run.
Note that under the winnt MPM model, recycling the only request serving process that Apache contains, can present a problem for some sites with constant and heavy traffic.
Requests vs. Client Connections
On any given connection, to load a page, a client may request many URLs: page, site css files, javascript files, image files, etc.
Multiple requests from one client in rapid succession can have the same effect on a Server as "concurrent" connections [threaded MPMs and directive KeepAlive taken into consideration]. If a particular website requires 10 requests per page, 10 concurrent clients will require MPM settings that are geared more towards 20-70 clients. This issue manifests itself most under a process-based MPM [prefork].
Separate Static and Dynamic Content
Use separate servers for static and dynamic content. Apache processes serving dynamic content will carry overhead and swell to the size of the content being served, never decreasing in size. Each process will incur the size of any loaded PHP or Perl libraries. A 6MB-30MB process size [or 10% of server's memory] is not unusual, and becomes a waist of resources for serving static content.
For a more efficient use of system memory, either use mod_proxy to pass specific requests onto another Apache Server, or use a lightweight server to handle static requests:
- lighttpd [has experimental win32 builds]
- tux [patched into RedHat, runs inside the Linux kernel and is at the top of the charts in performance]
The Server handling the static content goes up front.
Note that configuration settings will be quite different between a dynamic content Server and a static content Server.
mod_deflate
Reduce bandwidth by 75% and improve response time by using mod_deflate.
LoadModule deflate_module modules/mod_deflate.so
<Location />
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml application/x-javascript
</Location> Loaded Modules
Reduce memory footprint by loading only the required modules.
Some also advise to statically compile in the needed modules, over building DSOs (Dynamic Shared Objects). Very bad advice. You will need to manually rebuild Apache every time a new version or security advisory for a module is put out, creating more work, more build related headaches, and more downtime.
mod_expires
Include mod_expires for the ability to set expiration dates for specific content; utilizing the 'If-Modified-Since' header cache control sent by the user's browser/proxy. Will save bandwidth and drastically speed up your site for [repeat] visitors.
Note that this can also be implemented with mod_headers.
KeepAlive
Enable HTTP persistent connections to improve latency times and reduce server load significantly [25% of original load is not uncommon].
prefork MPM:
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 80 worker and winnt MPMs:
KeepAlive On
KeepAliveTimeout 15
MaxKeepAliveRequests 80 With the prefork MPM, it is recommended to set 'KeepAlive' to 'Off'. Otherwise, a client will tie up an entire process for that span of time. Though in my experience, it is more useful to simply set the 'KeepAliveTimeout' value to something very low [2 seconds seems to be the ideal value]. This is not a problem with the worker MPM [thread-based], or under Windows [which only has the thread-based winnt MPM].
With the worker and winnt MPMs, the default 15 second timeout is setup to keep the connection open for the next page request; to better handle a client going from link to link. Check logs to see how long a client remains on each page before moving on to another link. Set value appropriately [do not set higher than 60 seconds].
SymLinks
Make sure 'Options +FollowSymLinks -SymLinksIfOwnerMatch' is set for all directories. Otherwise, Apache will issue an extra system call per filename component to substantiate that the filename is NOT a symlink; and more system calls to match an owner.
<Directory />
Options FollowSymLinks
</Directory> AllowOverride
Set a default 'AllowOverride None' for your filesystem. Otherwise, for a given URL to path translation, Apache will attempt to detect an .htaccess file under every directory level of the given path.
<Directory />
AllowOverride None
</Directory> ExtendedStatus
If mod_status is included, make sure that directive 'ExtendedStatus' is set to 'Off'. Otherwise, Apache will issue several extra time-related system calls on every request made.
ExtendedStatus Off Timeout
Lower the amount of time the server will wait before failing a request.
Timeout 45 Other/Specific
Cache all PHP pages, using Squid, and/or a PHP Accelerator and Encoder application, such as APC. Also take a look at mod_cache under Apache 2.2.
Convert/pre-render all PHP pages that do not change request-to-request, to static HTML pages. Use 'wget' or 'HTTrack' to crawl your site and perform this task automatically.
Pre-compress content and pre-generate headers for static pages; send-as-is using mod_asis. Can use 'wget' or 'HTTrack' for this task. Make sure to set zlib Compression Level to a high value (6-9). This will take a considerable amount of load off the server.
Use output buffering under PHP to generate output and serve requests without pauses.
Avoid content negotiation for faster response times.
Make sure log files are being rotated. Apache will not handle large (2gb+) files very well.
Gain a significant performance improvement by using SSL session cache.
Outsource your images to Amazon's Simple Storage Service (S3).
Measuring Web Server Performance
Load Testing
Apache HTTP server benchmarking toolhttperf
The Grinder, a Java Load Testing Framework
Benchmarks
I have searched extensively for Apache, lighttpd, tux, and other webserver benchmarks. Sadly, just about every single benchmark I could locate appeared to have been performed completely without thought, or with great bias.
Do not trust any posted benchmarks, especially ones done with the 'ab' tool.
The only way to get a valid report is to perform the benchmark yourself.
For valid results, note to test under a system with limited resources, and maximum resources. But most importantly, configure each httpd server application for the specific situation.
Information
System Tuning Info for Linux ServersScott Wiersdorf
Wed Nov 19 01:01:14 MST 2003
$Id: tuning.html,v 1.4 2004/04/08 06:24:10 scott Exp $
MaxRequestsPerChild
If you're serving dynamic content, you'll want to exercise your site to determine optimal settings:- restart_apache
- run 'top' in a terminal window
- hit your site hard with ab or some other web server exerciser for 5 minutes or so
- watch the size of the Apache children in 'top' during the exercise
- if the size of the children does not grow, or grows a little but then stops growing, you can safely assume that there are no memory leaks and you can set your MaxRequestsPerChild to zero
- if the size of the children continues to grow over the duration of the exercise, you are using a component (frontpage, some ImageMagick stuff, PHP, etc.) that has a memory leak. Start your test again (beginning with restart_apache) and run the exerciser with fewer total hits. Lather, rinse, repeat. Do this until you find a total number of hits that is acceptable (i.e., the children are not yet too bloated) and that is not too small (otherwise you'll be killing off the children and the cost of forking will become the dominant performance factor). This is the 5000-10000 range, usually, but depends completely on how bad your memory leak is.
KeepAlives
KeepAlives, from the manual, "provide long-lived HTTP sessions which allow multiple requests to be sent over the same TCP connection. In some cases this has been shown to result in an almost 50% speedup in latency times for HTML documents with many images".
If the typical HTTP "hit profile" on your site does not involve multiple HTTP requests (see example below), you won't benefit from KeepAlives because once the request has been served (and no more are expected from this client for serveral seconds), the socket remains open, unused and consuming server resources that could otherwise be used for other connections. This is what is happening while your site is being very slow: the server is waiting for all those KeepAlive connections to "time out" so it can server other clients.
Example: Your typical request is for a web page and several dozen images. It usually takes your If your average client is a broadband user OR for whatever reason you can see that the average total request per page (including images and other dependencies) is only 2 seconds, then you should reduce your timeout to 2 seconds. KeepAliveTimeout - How long is an average session? By setting your timeout high, clients benefit from a quicker response from your server and your server uses fewer resources to service it. By setting this too high, Apache children are tied up waiting for clients when they could be servicing new clients. MaxKeepAliveRequests - How many requests maximum through a keepalive connection? If you have a site with fewer visitors at any given moment than you have available Apache children your clients can benefit from a high MaxKeepAliveRequests setting. Beware of greedy robots! They can suck your server dry in a single session if this is set too high. You can calculate your optimal setting by determining how many requests are made per session (a "session" is an average length of stay for your visitors). Note that this only works when the number of clients you service at any moment is fewer than the available Apache children. If you have more clients than available children, KeepAlive settings will hurt overall performance and should be turned off. nokeepalive - Here are some broken clients known to abuse the KeepAlive feature. You'll need to enable mod_setenvif, if it's not already enabled or compiled in your Apache: Send comments to the author ==================================================================================================================== [펌] http://2bits.com/articles/tuning-the-apache-maxclients-parameter.html One thing that can have a really drastic effect on a large site using Apache, is the value assigned to the MaxClients parameter. This parameter defines how many simultaneous request can be served. Any connection request from browsers that come in after that will be queued. In the most common case, you will be using Apache in the prefork mode, meaning one process per connection, with a pool of processes pre-forked to standby for connections. The number of spare processes is defined by the values MaxSpareServers, MinSpareServers, while the number to start is defined by StartServers. By default, the MaxClients parameter has a compiled in hard limit of 256. This can be changed by recompiling Apache however. Some distributions, or hosting companies raise this limit to a very high value, such as 512 or even 1024 in order to cope with large loads. While this makes sense when the web server is serving static content (plain HTML, images, ...etc.), it can be detrimental to a dynamic web application like Drupal. So often, we have clients calling because their web server has grind to a halt, and the reason would be a too high MaxClients value. The reason is that if your web site experiences a traffic spike, or if there is a bottleneck in the database, incoming requests cause new processes to be forked at a rate higher than old processes can service the older connections. This causes a condition where the system keeps creating new processes that overflow the available memory and starts to use the swap space. This almost always causes thrashing, where the system is just swapping pages from physical memory to virtual memory (on disk), and vice versa, without doing any real work. You can detect if thrashing has occurred by using the vmstat command (see our page on tools for performance tunings and optimization for more info). A simple calculation for MaxClients on a system that does only Drupal would be: (Total Memory - Operating System Memory - MySQL memory) / Size Per Apache process. If your hosting company configured your server with all sorts of bells and whistles (like mod_perl, mod_python, in addition to mod_php), then Apache can easily be 21 MB per process. If your server has 512MB, then you can fit some 20 Apache processes. If you tune Apache well, and remove all the unneeded modules, and install a PHP op-code cache/accelerator, then you can make each Apache process take as little as 12 MB. These figures depend on how many modules you have loaded, how big they are, so there is no hard and fast rule. Even if one has 1GB of memory, and leaves 250 MB for the system and MySQL, with an Apache process of 15MB, this means 50 Apache processes can fit in the remaining 750MB. Remember that you need memory for the operating system, as well as for MySQL. The more you give the system and MySQL memory, the more caching of the file system they do for you and avoid hitting disk, so do not use the very last available memory for MaxClients. On some systems, there is another parameter that sets an upper limit if MySQL. So for example, if ServerLimit is set by default to 256, and you want to increase MaxClients to 300, you will not be able to do so, until you set ServerLimit to 300 as well. Normally, you would see a warning message from Apache when you restart it to tell you that this needs to be done. If you cannot do a proper calculation, then it is safest to start with a conservative number, e.g. 60 to 150 on a 2GB system, and then increase it as you monitor the usage of the system over a few weeks. By all means, do not keep it at the 512 value that came with your server/distribution until you know how much load you can handle. ===================================================================================================================== I have a plesk (7.5.2 box) running with Redhat 9. This machine (Pentium 4 1024 mhz) was running fine for quite a long time. This week one of my sites became very populair and this gives me some troubles. The apache server stops to work and I need to restart it within every 10 minutes. Then apache is up and after 10 minutes its down again. The server log said this: [error] server reached maxclients setting, consider raising the maxclients setting So I changed the maxclients from 100 to 256. //etc/init.d/httpd status This is my current httpd.conf: /KeepAlive Off <IfModule prefork.c> <IfModule worker.c> <IfModule perchild.c> Please let me know how I can solve this problem!
BrowserMatch "Mozilla/2" nokeepalive
See the official Apache performance tuning documentation at:
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
http://httpd.apache.org/docs/misc/perf-tuning.html
Tuning the Apache MaxClients parameter
Apache prefork, StartServers, MaxSpareServers and MinSpareServers
Maxclients default
A web site's nemesis: Excessive Thrashing
Tuning the ServerLimit
Conclusion
Resources and Links
This will increase the dying time from 10 minutes till 20 minutes but does not solve the problem. When I check the apache status I see this:
httpd (pid 5073 5072 5071 5070 5069 5068 5067 5065 5064 5063 5062 5061 5060 5059 5058 5057 5056 5055 5054 5053 5052 5051 5050 5049 5048 5034 5033 5032 5031 5030 5029 5028 5027 5026 5025 5024 5023 5022 5021 5019 5018 5010 5009 5008 5007 5006 5004 5003 5002 4998 4997 4995 4994 4991 4990 4988 4953 4952 4951 4950 4949 4947 4946 4945 4944 4943 4942 4941 4940 4939 4938 4937 4936 4935 4934 4933 4932 4930 4929 4928 4927 4926 4925 4924 4923 4922 4921 etc etc etc/
MaxKeepAliveRequests 100
KeepAliveTimeout 15
StartServers 8
MinSpareServers 5
MaxSpareServers 20
maxclients 256
MaxRequestsPerChild 1000
</IfModule>
StartServers 2
maxclients 256
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
NumServers 5
StartThreads 5
MinSpareThreads 5
MaxSpareThreads 10
MaxThreadsPerChild 20
MaxRequestsPerChild 0
</IfModule>/
0 개의 댓글:
댓글 쓰기