Benchmarking Authenticated Drupal Users with ApacheBench
The sections of this tutorial are as follows:
- Brief background on ApacheBench and performance of Drupal Anonymous vs Authenticated Users
- Accessing the cookie containing the Drupal session ID
- Passing the session cookie to ApacheBench
- Verifying that the Drupal installation being benchmarked recognizes the cookie and is serving authenticated Pages
ApacheBench, also known as 'ab', is a command line program bundled with the Apache Web Server that measures the performance of web servers by making HTTP requests to a user-specified URL. ApacheBench displays statistical information, such as the number of requests served per second and the amount of time taken to serve those requests, that is useful for evaluating (benchmarking) and tuning the performance of a webserver. ApacheBench does a decent job of simulating different types and levels of load on a sever.
Many Drupal websites make use of Drupal's core caching functionality, which typically improves performance for anonymous users (users who are not-logged in) by a factor of 10 times, measured in requests served per second. The cache system achieves this performance improvement by storing the results of certain database queries in designated cache tables, allowing Drupal to avoid repeating expensive or frequently run database queries. Drupal does not cache page content for authenticated users because Drupal's permissions system (and node_access restrictions) can show different content depending on a user's role and because some elements of the page are user-specific. Since authenticated users are typically served non-cached pages, requests served to them are more resource intensive and therefore take longer to conduct than requests served to anonymous users.
By default, ApacheBench requests pages as one or multiple concurrent anonymous users. Benchmarks of performance for anonymous users can be useful for a website that most users will access anonymously, but these data do not accurately describe the performance of websites that serve a significant percentage of their total pages served to authenticated users (as most community sites tend to do). By providing the Drupal session cookie information, ApacheBench can perform benchmarking tests as an authenticated Drupal user.
Accessing the cookie containing the session ID:
Note: These instructions are for the Mozilla Firefox browser.
1)Log into your Drupal installation using the account that you'd like ApacheBench to use when conducting its tests.
2)Open the Firefox preferences menu and browse to the 'Privacy' Tab
3)Click the 'Show Cookies' button
4)Browse the list of sites to find the site that you have just logged into.
5)Highlight the cookie associated with your site that has a 'Cookie Name' value beginning with 'SESS'. There should be only one of these cookies. If you have two cookies with names beginning with 'SESS' for the same Drupal website, you should clear both of these cookies (which will log you out of your Drupal site) and log back in to ensure that you are specifying the correct cookie in ApacheBench.
6)You'll see that your site's SESS cookie has both 'Name' and 'Content' values. You're going to copy each of these values individually and pass them inside of a command line parameter to ab. Note: Do not log out of your Drupal site before testing with ab, as doing so will invalidate the cookie information you have just copied!
Passing the session cookie to ApacheBench
The 'C' parameter is used with ApacheBench to specify a cookie. This parameter is case sensitive, and should not be confused with 'c' (lowercase) which specifies the number of concurrent requests ApacheBench will make. You'll describe your site's cookie using the following format:
-C 'NAME=CONTENT'
There is no space between the equals sign. Below is a completed example specifying that 400 requests will be made (-n 400) with 10 simultaneous requests (-c 10):
ab -n 400 -c 10 -C 'SESS5a2cb35dfce80bc682796cc451440ac0=d45b85c5be4c651ea2ad520947082e04' http://example.com/
Verifying that Drupal accepts the cookie and is serving pages to an authenticated user
It's important to verify that Drupal recognizes and accepts the cookie that corresponds to your session. Once, while performing a set of ab authenticated Drupal user benchmarks, I adjusted a Drupal cache setting that increased the number of requests served per second for authenticated users from 5 to 60. I thought, “Wow! I've made an enormous improvement!” What I had actually done was switched from Drupal core session handling to Memcahe's session handling, which caused Drupal to not recognize my cookie. Drupal was actually serving anonymous pages, which accounted for the dramatic “performance improvement.” To avoid misunderstandings like this one, we'll use ApacheBench's verbose mode to confirm that Drupal is serving authenticated pages.
In our theme directory, we'll add a PHP snippet to page.tpl.php below the HEAD tag, that will print, inside an HTML comment tag, the username and uid (user id) of the user currently viewing the page.
<?php global $user; print 'This is user: '. $user-?>name .' : UID:'. $user->uid; ?>
Then, we'll run ApacheBench with a verbosity level of 4 (parameter -v4), allowing us to view the HTTP response code and html that the server is sending to ab.
Viewing the content of pages served to ab is also useful in determining the nature of failed responses and investigating suspiciously high numbers of requests served per second. Apache identifies certain types of failed requests by serving them with an unsuccessful (non-200) HTTP response code. (For more about HTTP response codes\status codes, see the W3's "Status Code Definitions" .) ApacheBench recognizes HTTP response codes and reports the number of responses that are marked as successful and unsuccessful by Apache. A reportedly high number of requests successfully served per second can indicate good server performance, but it's important to distinguish pages served with a 200 response code from those that are truly served successfully. In some situations, Apache is unaware of serious problems that occur in other parts of the server stack and will serve pages with an HTTP response code of 200 (successful) despite the fact these pages contain only a PHP fatal error. In these cases, Apache is “successfully” serving the PHP fatal error message.
Drupal correctly specifies non-200 HTTP response codes when it is unable to connect to the database. Viewing the content of the benchmarked page allows the person performing the testing to view the specific error message that the site is displaying. This is useful in identifying that the problem is, for example, that the MySQL max_user_connections value has been reached, as opposed to other database connection errors, such as an Access Denied error.
It's worth noting that while ab provides useful information about a server's performance, that it does not predict exactly how a server will perform under load from actual users.
Questions? Comments? Corrections? I'm happy to hear from you.
Tags: