Tag Archive for 'performance'

Optimize hard disk performance in Linux; benchmarks on Slicehost

A three-pronged attack on performance” is a good read on improving performance in Linux. One performance enhancing setting is the hard disk’s readahead value. Unfortunately, there is no magical readahead value that will optimize your hard disk’s performance; you must run your own benchmarks. I used the following code to benchmark disk performance (12 times) at each readahead value on my 256MB Slicehost VPS.

for ((i=0;i<12;i++)); do sudo hdparm -t /dev/sda1; done

The average disk read speeds at each readahead value are as follows:

“hdparm -a128 /dev/sda1″ - 65.69 mb/sec
“hdparm -a256 /dev/sda1″ - 104.44 mb/sec
“hdparm -a512 /dev/sda1″ - 114.54 mb/sec
“hdparm -a1024 /dev/sda1″ - 119.39 mb/sec
“hdparm -a2048 /dev/sda1″ - 122.82 mb/sec

It appears that on my Slicehost VPS, “hdparm -a2048” yields the best performance. To ensure that this readahead value is used at all times, I instruct hdparm to set it on every bootup by adding the following line to /etc/conf.d/local.start

hdparm -a2048 /dev/sda1

More details and documentation on Slicehost’s Wiki.

If you liked this post, please subscribe to my feed. Thanks for visiting!

Speed up PHP with XCache on Gentoo Linux

XCache is a PHP opcode cacher created by the same developer who brought us Lighttpd. An opcode cacher significantly increases PHP’s performance by caching the compiled state of PHP code to avoid time-consuming recompilation each time a script is executed. There are a handful of great opcode cachers on the market currently, incuding APC and eAccelerator (here’s a more comprehensive list). APC is written by some of the developers of PHP and will be bundled with PHP6. eAccelerator has a long history and might be the most popular and widely supported opcode cacher. I chose XCache due to its reputation for superior performance (source) and its ability to take advantage of multi-core processors.

Setting up XCache on Gentoo Linux is dead simple.

Install XCache

emerge -va dev-php5/xcache

Configure XCache

nano /etc/php/cgi-php5/ext-active/xcache.ini

Edit anything you see fit. See this page for details.
Since Slicehost is running on twin dual-core processors, I changed “xcache.count” to 5 (n+1 where n is the number of processors) to take advantage of the Splitted Cache feature.

Restart PHP
I have PHP running as a FastCGI daemon, so I restart with

/etc/init.d/fcgi.php restart

Check phpinfo() to verify that XCache is loaded. You should see the following in the “Powered by Zend” box:

with XCache v1.2.1, Copyright (c) 2005-2007, by mOo

Nginx with PHP as FastCGI on Gentoo Linux

Nginx (pronounced “Engine X”) is a high performance web server (and proxy server, but we will be using it as a web server here). In small VPS environments where memory is precious, Apache is at best overkill and uses memory that could be spent elsewhere (like MySQL query caching), at worst a terrible bottleneck that will consistently bring down your site under very moderate loads. If you are willing to live without .htaccess files and Apache-style mod_rewrite rules, Nginx is a great replacement that will lower memory usage and increase performance.

This is a draft. Comments, suggestions, corrections, improvements are very much welcome!

Continue reading ‘Nginx with PHP as FastCGI on Gentoo Linux’

Zenphoto plugin: Static Cache Control

Stealing a page from WP Super Cache’s book, I’ve written a plugin for Zenphoto that caches (and optionally gzips) Zenphoto pages on the file system to minimize PHP execution, making your dynamic image gallery run almost as fast and light on resources as a static website. Read more about Zenphoto staticCacheControl here.

Nagging question:
Using PHP, is it impossible to redirect a browser to a different URL without changing the browser’s URL visibly? In other words, can transparent URL rewriting Apache-style be accomplished with PHP?

Zenphoto plugin: Static Cache Control

staticCacheControl is a plugin that caches (and optionally gzips) Zenphoto pages on the file system to minimize PHP execution, making your dynamic image gallery run as fast and light on resources as a static website.

This is a beta release. staticCacheControl has been tested on my private Zenphoto installation but not on a “live” site. Please send me any feedback, suggestions, improvements, criticisms.

No matter how well you optimize PHP processing through code optimizations, opcode and database query caching, a dynamic PHP application still can’t beat the performance (speed/time, CPU/memory usage) of a website with the same content displayed using static HTML files. However, good luck updating thousands of static HTML pages by hand. :P With staticCacheControl, you can have the best of both worlds.

staticCacheControl automates the process of generating static HTML copies of your Zenphoto pages, redirecting visitors to these cached pages when possible, and also the validating/refreshing of the static cache when your Zenphoto pages change. Thus, you can enjoy the performance of static pages without the hassle of updating them manually.

This plugin is designed for use in the album.php, albumarchive.php, image.php, index.php of your theme. It can be used in conjunction with (after) httpCacheControl for optimal results.

Example usage:
Place static_cache_control.php in your theme directory, like “/themes/default“. Insert one of the following chunks of code at the top of your theme’s index.php, like “/themes/default/index.php” (but after httpCacheControl() if present)

include_once('static_cache_control.php');
staticCacheControl(__FILE__);

Or, enable gzip compression

staticCacheControl(__FILE__, 0, true);

If you got $mtime from elsewhere, like

$mtime = httpCacheControl(__FILE__);

then pass $mtime

staticCacheControl(__FILE__, $mtime, true);

The first required parameter is the path to the file that should be used to calculate Last Modified date, usually “__FILE__”.

The second optional parameter is the Last Modified date of this page. If another function, like httpCacheControl(), already calculated the Last Modified date, be sure to pass the value using this second parameter to avoid redundant calculations. If omitted or set to 0, staticCacheControl will attempt to calculate the Last Modified date, so httpCacheControl is not required.

The third optional parameter specifies whether staticCacheControl should gzip compress cached pages. If omitted, gzip files will not be created.

Read on for .htaccess code to minimize PHP execution further.

How it works:
staticCacheControl generates static HTML caches of Zenphoto pages, optionally applies gzip compression, and stores them on the file system for future retrieval with minimal PHP processing. Static cached pages are stored in the “/ZENPHOTO/cache/static” directory where “ZENPHOTO” is your installation directory. The directory structure in the static cache mirrors the URLs used to access Zenphoto pages. For example, the page

/ZENPHOTO/album/img.jpg/suffix

is cached to

/ZENPHOTO/cache/static/album/img.jpg/suffix/index.html(.gz)

When a Zenphoto page is requested, staticCacheControl automatically redirects the client to the static cache if the cache is fresh; the gzipped cache file is used if gzip is enabled and the client accepts gzip. If the cache is does not exist or is stale, staticCacheControl creates/updates the static cache file. This plugin uses the same logic as httpCacheControl to determine if a cache is stale. Please see this page for details.

PHP processing can be further minimized by using .htaccess directives such that the web server handles the redirection automatically and transparently. Insert the following code after the “RewriteBase” line and before other “RewriteCond” and “RewriteRule” lines in Zenphoto’s .htaccess.

# BEGIN staticCacheControl redirection
  # Redirect if current second is greater than 10
  # Visits during seconds 1-10 (i.e. 1 in 6 visits on average) will execute PHP to validate cache
  # 0-58: the larger the number, the more likely PHP will be executed to validate cache
  # Comment out if you have some other method to periodically validate/freshen your static cache
  RewriteCond %{TIME_SEC} >10
  # Redirect if user isn't an admin or hasn't left a comment, signified by lack of a zenphoto cookie
  RewriteCond %{HTTP_COOKIE} !^.*zenphoto.*$
  RewriteCond %{HTTP:Accept-Encoding} gzip
  # Check if the cache file exists
  # !! Replace 4 instances of ZENPHOTO below with your installation directory !!
  RewriteCond %{DOCUMENT_ROOT}/ZENPHOTO/cache/static/$1/index.html.gz -f
  # Redirect any URL starting with "RewriteBase" and ending with a "/" or not
  # Don't save the trailing slash
  RewriteRule ^(.*)/?$ /ZENPHOTO/cache/static/$1/index.html.gz [L]
 
  RewriteCond %{TIME_SEC} >10
  RewriteCond %{HTTP_COOKIE} !^.*zenphoto.*$
  RewriteCond %{DOCUMENT_ROOT}/ZENPHOTO/cache/static/$1/index.html -f
  RewriteRule ^(.*)/?$ /ZENPHOTO/cache/static/$1/index.html [L]
# END staticCacheControl redirection

The problem with bypassing PHP execution is that you still must somehow validate or refresh your cache periodically. Thus, the above directives do not bypass PHP execution all the time. The code

RewriteCond %{TIME_SEC} >10

forces ~1 in 6 visitors, on average, to execute the PHP code to validate the cache. (Visitors from the 0th to 10th second of each minute execute PHP code and trigger cache validation; visitors from the 11th to 59th second of each minute are transparently redirected to the static cache.) Admins and visitors who leave comments also execute PHP to validate the cache. If you have a more elegant method of validation, please share!

Ideas:

  • Use a cron job to periodically delete the entire “/ZENPHOTO/cache/static” directory and redirect ALL visitors to static cache 100% of the time?
  • Invalidate more than just the currently viewed page (ex. the entire album) if a cached page is stale?
  • Execute PHP to validate cache for a longer chunk of time during off-peak hours (ex. 1AM-6AM) instead of doing that for a few seconds every minute?

Performance:
From my rudimentary profiling, execution of staticCacheControl takes from less than 10 milliseconds to a few dozen milliseconds on my shared hosting service. Thus, in the case where PHP is executed and the static cache is fresh, this plugin cuts your page’s execution time down from hundreds of milliseconds to ~10-50ms. In the case where the web server transparently redirects you to the static cache, 0ms is spent on PHP execution. In the case where the static cache is stale or doesn’t exist, your page takes an extra ~10-50ms to load. Also remember that time is not the only resource saved.

Note that benchmarks were performed in a PHP5 environment. PHP4-compatible functions are included but not tested (yet).

Download:

zenphoto_static_cache_control.zip

FAQ:
Q: Why aren’t the .htaccess directives working? I am visibly redirected to the cache file URL every time.
A: Are you an admin or have left a comment on the site? If so, you have a *zenphoto* cookie, and you will execute PHP code instead of getting redirected by the web server. Try clearing your cookies, using a different browser or computer.

Known issues:

  • Redirection by PHP (rather than web server URL rewriting) is visible to the user as the URL of the page changes to the URL of the static cached file. Page navigation is unaffected; it’s just inelegant. I don’t believe it is possible to redirect in PHP transparently, is it?
  • Static cache validation/refreshing is inelegant. PHP execution is required to validate a cache file; the more often we bypass PHP execution, the higher the likelihood of stale cache files not getting invalidated. To-Do: actions performed in Admin pages should trigger cache validations, but this would require modifying zp-core files.
  • /etc/mime.types on some servers, like Red Hat and CentOS, have (erroneously?) an entry for gzip, causing *.html.gz files to be sent with a “Content-Type: application/x-gzip” header. Browsers will barf unless gzip compressed files are sent with a “Content-Type: text/html” header. Work around this by creating a .htaccess file in “/ZENPHOTO/cache” with the following directives:
    AddEncoding x-gzip .gz
    AddType text/html .gz

Changelog:
December 02, 2007

  • added support for comments; last modified time calculations include the date of the most recent comment
  • comments can also be submitted from a static cache page

November 30, 2007

  • first public release

Credits:
Inspired by Donncha O Caoimh’s WP Super Cache. Workaround for gzip Content-Type by Dennis.

Zenphoto plugin: Link Prefetching Hints

printPrefetchHints is a plugin that improves Zenphoto image browsing performance by printing link prefetching hints which instruct Mozilla-based browsers to preload the next page and image in the album.

Link prefetching hints are only supported by Mozilla-based browsers. The hints are completely harmless as they are ignored by other browsers like Internet Explorer. You can test your browser to see if it supports prefetching.

Zenphoto plugin: Link Prefetching Hints

printPrefetchHints is a plugin that improves Zenphoto image browsing performance by printing link prefetching hints which instruct Mozilla-based browsers to preload the next page and image in the album.

Link prefetching hints are only supported by Mozilla-based browsers. The hints are completely harmless as they are ignored by other browsers like Internet Explorer. You can test your browser to see if it supports prefetching.

Example Usage:
Insert in the <HEAD> section of your theme’s image.php:

include_once('print_prefetch_hints.php');
printPrefetchHints();

You may pass an optional parameter to printPrefetchHints() to use an image size other than the default image size in your Zenphoto settings.

How it works:

Link prefetching is a browser mechanism, which utilizes browser idle time to download or prefetch documents that the user might visit in the near future. A web page provides a set of prefetching hints to the browser, and after the browser is finished loading the page, it begins silently prefetching specified documents and stores them in its cache. When the user visits one of the prefetched documents, it can be served up quickly out of the browser’s cache.

Please read the Link prefetching FAQ for more information on this mechanism.

Performance:
From my rudimentary profiling, this plugin generally takes less than 10 milliseconds to execute on my shared hosting service.

Download:

zenphoto_print_prefetch_hints.zip

Changelog:
November 29, 2007

  • First public release