Sleuthing

Knowing how to evaluate the performance and scalability of a system allows you to quickly isolate and respond to system bottlenecks with confidence, even amid a crisis. You can discover where bottlenecks lie with a few simple tools and by asking questions along the way. Here's one way to approach a badly performing server. We begin with the knowledge that performance is going to be bound by one of the following variables: CPU, RAM, I/O, or bandwidth. So begin by asking yourself the following questions:

Is the CPU maxed out? If examining CPU usage with top on Unix or the Task Manager on Windows shows CPU(s) at 100 percent, your mission is to find out what's causing all that processing. Looking at the process list will let you know whether it's the web server or the database eating up processor cycles. Both of these problems are solvable.

Has the server run out of RAM? This can be checked easily with top on Unix or the Task Manager on Windows. If the server has plenty of free memory, go on to the next question. If the server is out of RAM, you must figure out why.

Are the disks maxed out? If examining the disk subsystem with a tool like vmstat on Unix or the Performance Monitor on Windows shows that disk activity cannot keep up with the demands of the system while plenty of free RAM remains, you've got an I/O problem. Possibilities include excessively verbose logging, an improperly configured database that is creating many temporary tables on disk, background script execution, improper use of a RAID level for a write-heavy application, and so on.

Is the network link saturated? If the network pipe is filled up, there are only two solutions. One is to get a bigger pipe. The other is to send less information while making sure the information that is being sent is properly compressed.

Web Server Running Out of CPU

If your CPU is maxed out and the process list shows that the resources are being consumed by the web server and not the database (which is covered later), you should look into reducing the web server overhead incurred to serve a request. Often the execution of PHP code is the culprit.

PHP Optimizations

Because PHP code execution is a big part of serving a request in Drupal, it's important to know what can be done to speed up this process. Significant performance gains can be made by caching PHP operation codes (opcodes) after compilation and by profiling the application layer to identify inefficient algorithms.

Operation Code Caching There are two ways to reduce the CPU resources used to execute PHP code. Obviously, one is to reduce the amount of code by disabling unnecessary Drupal modules and writing efficient code. The other is to use an opcode cache. PHP parses and compiles all code into an intermediate form consisting of a sequence of opcodes on every request. Adding an opcode cache lets PHP reuse its previously compiled code, so the parsing and compilation are skipped. Common opcode caches are Alternative PHP Cache (http://pecl.php.net/ package/APC), eAccelerator (http: //eaccelerator.net), XCache (http ://trac .lighttpd .net/ xcache/), and Zend Platform (http://zend .com). Zend is a commercial product while the others are freely available.

Because Drupal is a database-intensive program, an opcode cache should not be regarded as a single solution but as part of an integrated strategy. Still, it can give significant performance gains for minimal effort.

Figure 22-1. Alternative PHP Cache (APC) comes with an interface that displays memory allocation and the files currently within the cache.

Application Profiling Often custom code and modules that have performed reasonably well for small-scale sites can become a bottleneck when moved into production. CPU-intensive code loops, memory-hungry algorithms, and large database retrievals can be identified by profiling your code to determine where PHP is spending most of its time and thus where you ought to spend most of your time debugging. See Chapter 21 for more information on PHP debuggers and profilers.

If, even after adding an opcode cache and optimizing your code, your web server cannot handle the load, it is time to get a beefier box with more or faster CPUs or to move to a different architecture with multiple web server frontends.

Web Server Running Out of RAM

The RAM footprint of the web server process serving the request includes all of the modules loaded by the web server (such as Apache's mime_module, rewrite_module, etc.) as well as the memory used by the PHP interpreter. The more web server and Drupal modules that are enabled, the more RAM used per request.

■Note The maximum amount of memory allocated to the PHP interpreter is set by the value of memory_limit within PHP's php. ini file. The default value is 8MB, which should be doubled at least to run Drupal with enough breathing room. The memory_limit directive is only effective if your PHP was compiled with Denable-memory-limit.

Because RAM is a finite resource, you should determine how much is being used on each request and how many requests your web server is configured to handle. To see how much real RAM is being used on average for each request, use a program like top to see your list of processes. In Apache, the maximum number of simultaneous requests that will be served is set using the MaxClients directive. A common mistake is thinking the solution to a saturated web server is to increase the value of MaxClients. This only complicates the problem, since you'll be hit by too many requests at once. That means RAM will be exhausted, and your server will start disk swapping and become unresponsive. Let's assume, for example, that your web server has 2GB of RAM and each Apache request is using roughly 20MB (you can check the actual value using top). You can calculate a good value for MaxClients by using the following formula; keep in mind the fact that you will need to reserve memory for your operating system and other processes:

2GB RAM / 20MB per process = 100 MaxClients

If your server consistently runs out of RAM even after disabling unneeded web server modules and profiling any custom modules or code, your next step is to make sure the database and the operating system are not the causes of the bottleneck. If they are, then add more RAM. If the database and operating system are not causing the bottlenecks, you simply have more requests than you can serve; the solution is to add more web server boxes.

■Tip Since memory usage of Apache processes tends to increase to the level of the most memory-hungry page served by that child process, memory can be regained by setting the MaxRequestsPerChild value to a low number, such as 300 (the actual number will depend on your situation). Apache will work a little harder to generate new children, but the new children will use less RAM than the older ones they replace, so you can serve more requests in less RAM. The default setting for MaxRequestsPerChild is 0, meaning the processes will never expire.

0 0

Post a comment