<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog @ a2o.si</title>
	<atom:link href="http://blog.a2o.si/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.a2o.si</link>
	<description>Un*x system engineering</description>
	<lastBuildDate>Tue, 01 Dec 2009 00:02:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Standalone preforking PHP application server framework</title>
		<link>http://blog.a2o.si/2009/08/18/standalone-preforking-php-application-server-framework/</link>
		<comments>http://blog.a2o.si/2009/08/18/standalone-preforking-php-application-server-framework/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 21:41:51 +0000</pubDate>
		<dc:creator>Boštjan Škufca</dc:creator>
				<category><![CDATA[Daemons]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.a2o.si/?p=117</guid>
		<description><![CDATA[What a lenghty title! But it does characterize well the thing I have been working on a couple of nights.
The idea consists of these basic prerequisites:
- sometimes I need to create small application that is not a standard web application,
- it could be necessary that it it running as root/other privileged user,
- it probably receives [...]]]></description>
			<content:encoded><![CDATA[<p>What a lenghty title! But it does characterize well the thing I have been working on a couple of nights.</p>
<p>The idea consists of these basic prerequisites:<br />
- sometimes I need to create small application that is not a standard web application,<br />
- it could be necessary that it it running as root/other privileged user,<br />
- it probably receives client connections from network,<br />
- I need to have total control of what it does, for security reasons,<br />
- I do not want to configure it, I want to write it.<br />
- I want it to be written in PHP, which is a commodity language.</p>
<p>Usually PHP is coupled with some web server software, which together then constitutes web application server. This is a standard setup. It involves installing a web server, like Apache or NginX or IIS etc, which then you have to configure to suit your needs. Then you have to add PHP to it, and configure that too.</p>
<p>But what if you do not want a WEB server, what if you want a CUSTOM application server that does not use HTTP protocol but some weird/invented/forgotten/X protocol that you find suitable for your purpose?</p>
<p>This is why I have written this framework. You do not have to start from scratch, if you do not want to. What it does is this:<br />
- starts and daemonizes<br />
- forks as many children as needed<br />
- children start waiting for connections<br />
- when connection arrives, one of the children accepts the connection<br />
- here your custom processing part starts &#8211; you start by rewriting the $this->worker_handleClient() or $this->worker_handleRequest() method, like below:</p>
<blockquote><p>
<?php</p>
<p>class AppSrvDemo extends A2o_AppSrv<br />
{<br />
&nbsp;    protected function worker_handleClient ($clientSocket, $clientIp, $clientPort)<br />
&nbsp;    {<br />
&nbsp;&nbsp;        // You can do some socket reading here<br />
&nbsp;&nbsp;        $message = "Hello, Client!\n";<br />
&nbsp;&nbsp;        socket_write($clientSocket, $message, strlen($message));<br />
&nbsp;&nbsp;        $this->worker_closeConnection();<br />
&nbsp;    }<br />
}
</p></blockquote>
<p>And that is basically it. Framework handles the rest of the story, accepts multiple simultaneous connections, forks additional children, etc. There is still a lot to do but I managed to get first working daemon written in 10 minutes. It does fairly trivial job (accepting XML-RPC request and then su-ing to some specified user and running some shell command) but what seemed miles away once is now easily achieved. </p>
<p>If you need it, enjoy it. Here is the URI:<br />
<a href="http://github.com/bostjan/PHP-application-server/">Standalone preforking PHP application server framework</a>.</p>
<p>If you find some feature missing and/or you have prepared a patch for it, let me know in comments. Also, (constructive) critique is welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.a2o.si/2009/08/18/standalone-preforking-php-application-server-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>eAccelerator vs APC on PHP 5.2.9</title>
		<link>http://blog.a2o.si/2009/07/07/eaccelerator-vs-apc-on-php-5-2-9/</link>
		<comments>http://blog.a2o.si/2009/07/07/eaccelerator-vs-apc-on-php-5-2-9/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 09:57:49 +0000</pubDate>
		<dc:creator>Boštjan Škufca</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.a2o.si/?p=99</guid>
		<description><![CDATA[There is a single question to be answered: how does APC perform in comparison to eAccelerator on PHP 5.2.9?]]></description>
			<content:encoded><![CDATA[<h3>Motivation</h3>
<p>A year ago I was working on a website project which used <a href="http://www.php.net/">PHP</a> as a language of choice. The project development resulted in quite large amount of PHP code. After a brief research we decided that organising our code the way <a href="http://framework.zend.com/">Zend Framework</a> is organized is our way to go. While ZF&#8217;s <a href="http://framework.zend.com/manual/en/coding-standard.naming-conventions.html">naming conventions</a> are a nice and effective way to autoload classes and avoid naming conflicts, it is still a bit cumbersome at coding stage (long class names).</p>
<p>At that time I had my first glance at PHP 5.3 feature list and <a href="http://www.php.net/manual/en/language.namespaces.php">namespaces</a> seemed a good step forward from current practice. Unfortunately stable PHP 5.3 release was far from being released so I had to dump the namespace idea for that particular project. But I decided to migrate to PHP 5.3 as soon as possible.</p>
<p>Another part of the story is server administration. On all the servers I manage I utilise PHP opcode caching. Currently I use <a href="http://eaccelerator.net/">eAccelerator</a> and I am satisfied with it&#8217;s performance and stability. But eAccelerator&#8217;s website (at the moment of this writing) states nothing about PHP 5.3 support. Therefore I was forced to look elsewhere.</p>
<p>Many websites recommend <a href="http://pecl.php.net/package/APC">APC</a> with the suggestion that it is being actively maintained, unlike some other opcode caches. I remember back in year 2004 when I was testing it and comparing it to Turck MM cache that its performance sucked. Unfortunately I have no evidence to support my claim, but it is also irrelevant in 2009. Yet &#8220;actively maintained&#8221; phrase implies hope that APC supports PHP 5.3. And its <a href="http://pecl.php.net/package-info.php?package=APC&#038;version=3.0.19">changelog</a> confirms it.</p>
<p>First stable PHP 5.3 version was released last week and I was psyched to at least test it, but I did not want to be held back by an opcode caching solution, so I decided to compare eAccelerator and APC again. If APC performs as well as eAccelerator does (both on PHP 5.2.9), then I will seriously consider migration to PHP 5.3 and migration from eAccelerator to APC.</p>
<h3>Goal</h3>
<p>There is a single question to be answered: how does APC perform in comparison to eAccelerator on PHP 5.2.9?</p>
<h3>System setup</h3>
<p>I used exactly the same system with Apache web server as it is described in <a href="http://blog.a2o.si/2009/06/24/apache-mod_php-compared-to-nginx-php-fpm/">this article</a>. I only conducted &#8220;Application frontpage&#8221; test as it is the only relevant testcase.</p>
<p>I installed APC with the following command</p>
<blockquote><p>
printf &#8220;no\n&#8221; | /usr/local/httpd/php/bin/pecl install apc
</p></blockquote>
<p>and only enabled it in php.ini by adding</p>
<blockquote><p>
extension=&#8221;apc.so&#8221;
</p></blockquote>
<p>and removing eAccelerator, with no additional configuration.</p>
<h3>Why not PHP 5.3.0 or PHP 5.2.10?</h3>
<ul>
<li>PHP 5.3.0: simply because I have not yet tested it and upgraded the systems I manage.</li>
<li>PHP 5.2.10: simply because I tried to upgrade but the release is <a href="http://bugs.php.net/bug.php?id=48625">buggy</a>.</li>
</ul>
<h3>Results</h3>
<div id="attachment_101" class="wp-caption aligncenter" style="width: 648px"><a href="http://blog.a2o.si/wp-content/uploads/2009/07/eAc_vs_APC.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/07/eAc_vs_APC.png" alt="eAccellerator vs APC: application frontpage" title="eAccellerator vs APC: application frontpage" width="638" height="263" class="size-full wp-image-101" /></a><p class="wp-caption-text">eAccellerator vs APC: application frontpage</p></div>
<h3>Analysis of results and conclusion</h3>
<p>Performance results for both opcode cache solutions are almost identical, difference is negligible. Results at concurrency level higher than 128 are not reliable, I am in a phase of fixing that anomaly. From this test I can conclude that performance-wise you can safely choose any of these two opcode cache solutions.</p>
<h3>Stability</h3>
<p>I can not comment on the stability of APC more than that I have had no problems with it for this short period of testing time. I have no stability (<a href="http://2bits.com/articles/benchmarking-drupal-with-php-op-code-caches-apc-eaccelerator-and-xcache-compared.html">segfault</a>) problems with eAccelerator in the production environments.</p>
<h3>Info/status/control script</h3>
<p><del datetime="2009-11-30T23:58:38+00:00">What I DO miss with APC is a simple control.php which eAccelerator provides. It gives you an overview of caching statistics.</del><br />
Update (2009-12-01): Henrik Olsen notified me that APC also includes control script which provides an overview of caching statistics. See comments below for an URI of his article where he demonstrates the subject.</p>
<h3>Update</h3>
<p>As of today (2009-07-07) the compile results of eAccelerator and APC with PHP 5.3.0 are as follows:</p>
<ul>
<li>eAccelerator v0.9.5.3 &#8211; does not compile</li>
<li>APC stable v3.0.19 &#8211; does not compile</li>
<li>APC beta v 3.1.2 &#8211; compiles OK, but with some warnings about &#8220;&#8211;enable-spinlocks&#8221; being unrecognised and <i>warning: passing argument 1 of &#8216;zval_isref_p&#8217; discards qualifiers from pointer target type</i></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.a2o.si/2009/07/07/eaccelerator-vs-apc-on-php-5-2-9/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Apache + mod_php compared to Nginx + php-fpm</title>
		<link>http://blog.a2o.si/2009/06/24/apache-mod_php-compared-to-nginx-php-fpm/</link>
		<comments>http://blog.a2o.si/2009/06/24/apache-mod_php-compared-to-nginx-php-fpm/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 00:29:09 +0000</pubDate>
		<dc:creator>Boštjan Škufca</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://blog.a2o.si/?p=65</guid>
		<description><![CDATA[Recently I received an email pointing me to <a href="http://till.klampaeckel.de/blog/archives/30-PHP-performance-III-Running-nginx.html">this article</a> and with a request that I conduct a test of Nginx, which should supposedly be a better web serving application. But in previously mentioned article they state they are <strong>getting over a 500% more from the same hardware with a new piece of software, is still awesome</strong>. From the experience I know that with such claims, one must utilise some healthy skepticism.]]></description>
			<content:encoded><![CDATA[<p>Recently I received an email pointing me to <a href="http://till.klampaeckel.de/blog/archives/30-PHP-performance-III-Running-nginx.html">this article</a> and with a request that I conduct a test of Nginx, which should supposedly be a better web serving application. But in previously mentioned article they state they are <strong>getting over a 500% more from the same hardware with a new piece of software, is still awesome</strong>. From the experience I know that with such claims, one must utilise some healthy skepticism.</p>
<h3>Test methodology</h3>
<p>All the software was compiled from source (details below). Benchmarks were conducted using ApacheBench tool (ab) from apache installation. The tool was running on the same machine as the server. Both servers had request logging disabled. Tests were conducted once with keepalive feature enabled and once with keepalive disabled. Each test was repeated five times and average taken. Test files were:</p>
<ul>
<li><em>HelloWorld.php</em> &#8211; short php scripts, which only echoes string &#8220;Hello, World!&#8221; (13 bytes), intended to measure processing overhead of PHP vs static file (contents of this file are here: &#8216;<?php echo "Hello, World!"; ', without single quotes!)</li>
<li><em>HelloWorld.txt</em> &#8211; a static file with string &#8220;Hello, World!&#8221; inside (also 13 bytes), intended to show static file serving overhead</li>
<li><em>100KB.txt</em> &#8211; a static 100KB file</li>
<li><em>1MB.txt</em> &#8211; static 1MB file</li>
<li><em>index.php</em> &#8211; a frontpage of certain application which is quite CPU intensive and includes PHP processing, some DB querying, file cache reads and HTML template processing</li>
</ul>
<h3>Test system and ./configure commands</h3>
<ul>
<li>Hardware: HP DL380 G5</li>
<li>Hardware: 2x Intel Xeon E5420 (4 cores each, total of 8 cores)</li>
<li>Hardware: 8GB of ECC RAM</li>
<li>Hardware: Smart Array P400i RAID-1 with 2x 147GB SAS drives</li>
<li>OS: Slackware 12.2 with almost all software compiled from source</li>
<li>Filesystem: ext3</li>
<li>Apache version: 2.2.11, php via mod_php</li>
<li>Nginx version: 0.7.59, php via request proxying to php-fpm (via socket)</li>
<li>PHP version: 5.2.9</li>
<li>Eaccelerator version: 0.9.5.3 (for both, Apache and Nginx)</li>
<li>MySQL version: 5.0.77</li>
<li>OpenSSL version: 0.9.8k</li>
<li>both servers had request logging disabled</li>
</ul>
<p>Configure command for Apache:</p>
<blockquote><p>
./configure &#8211;prefix=/usr/local/$PDESTDIR_HTTPD &#8211;sysconfdir=/etc/httpd \<br />
  &#8211;enable-authn-file &#8211;enable-authn-default \<br />
  &#8211;enable-authz-host &#8211;disable-authz-groupfile &#8211;enable-authz-user &#8211;enable-authz-default \<br />
  &#8211;enable-auth-basic \<br />
  &#8211;disable-include &#8211;disable-filter &#8211;disable-charset-lite \<br />
  &#8211;enable-log-config \<br />
  &#8211;enable-env &#8211;enable-setenvif \<br />
  &#8211;enable-ssl &#8211;with-ssl=/usr/local/openssl-$PVERSION_OPENSSL \<br />
  &#8211;enable-http &#8211;enable-mime &#8211;enable-status \<br />
  &#8211;disable-autoindex &#8211;disable-asis \<br />
  &#8211;enable-info \<br />
  &#8211;enable-cgi &#8211;disable-cgid \<br />
  &#8211;enable-vhost-alias \<br />
  &#8211;disable-negotiation \<br />
  &#8211;enable-dir \<br />
  &#8211;disable-actions \<br />
  &#8211;disable-userdir \<br />
  &#8211;enable-info \<br />
  &#8211;enable-rewrite \<br />
  &#8211;enable-so \<br />
  &#8211;with-mpm=prefork
</p></blockquote>
<p>Configure command for Nginx:</p>
<blockquote><p>
./configure &#8211;prefix=/usr/local/$PDIR \<br />
  &#8211;conf-path=/etc/nginx/nginx.conf \<br />
  &#8211;error-log-path=/var/log/nginx/nginx_error.log \<br />
  &#8211;pid-path=/var/run/nginx.pid \<br />
  &#8211;lock-path=/var/run/nginx.lock \<br />
  &#8211;user=httpd \<br />
  &#8211;group=httpd \<br />
  &#8211;with-openssl=/usr/local/openssl-0.9.8k
</p></blockquote>
<p>Configure command for PHP:</p>
<blockquote><p>
&#8212;&#8211;[These lines are for PHP with Apache (mod_php)]&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
./configure &#8211;prefix=/usr/local/$PDESTDIR_HTTPD/$PDIR \<br />
  &#8211;with-apxs2=/usr/local/$PDESTDIR_HTTPD/bin/apxs &#8211;enable-cli &#8211;enable-cgi \<br />
  &#8211;with-config-file-path=/etc/php/httpd \</p>
<p>&#8212;&#8211;[These lines are for PHP with Nginx (php-fpm)]&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
./configure &#8211;prefix=/usr/local/php-fpm \<br />
  &#8211;enable-cli &#8211;enable-fastcgi &#8211;enable-fpm \<br />
  &#8211;with-fpm-conf=/etc/php/php-fpm/php-fpm.conf \<br />
  &#8211;with-fpm-log=/var/log/php-fpm.log \<br />
  &#8211;with-fpm-pid=/var/run/php-fpm.pid \<br />
  &#8211;with-config-file-path=/etc/php/php-fpm \</p>
<p>&#8212;&#8211;[These lines are common for both]&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
  &#8211;disable-short-tags \<br />
  &#8211;disable-ipv6 \<br />
  &#8211;disable-all \<br />
  \<br />
  &#8211;enable-libxml \<br />
  &#8211;with-openssl=/usr/local/openssl-$PVERSION_OPENSSL \<br />
  &#8211;with-pcre-regex \<br />
  &#8211;with-zlib \<br />
  &#8211;with-bz2 \<br />
  &#8211;with-curl &#8211;with-curlwrappers \<br />
  &#8211;enable-dba=shared &#8211;with-db4 &#8211;enable-inifile &#8211;enable-flatfile \<br />
  &#8211;enable-dom &#8211;with-libxml-dir \<br />
  &#8211;enable-filter \<br />
  &#8211;enable-ftp \<br />
  &#8211;with-gd &#8211;with-jpeg-dir &#8211;with-png-dir &#8211;with-freetype-dir \<br />
  &#8211;with-gettext \<br />
  &#8211;enable-hash &#8211;with-mcrypt \<br />
  &#8211;with-iconv=/usr/local/lib &#8211;with-iconv-dir=/usr/local/lib \<br />
  &#8211;with-imap=/usr/local/imap-$PVERSION_CYRUSIMAP &#8211;with-imap-ssl \<br />
  &#8211;enable-json \<br />
  &#8211;enable-mbstring &#8211;enable-mbregex &#8211;enable-mbregex-backtrack \<br />
  &#8211;with-mysql=/usr/local/mysql-$PVERSION_MYSQL &#8211;with-mysqli=/usr/local/mysql-$PVERSION_MYSQL/bin/mysql_config \<br />
  &#8211;enable-pdo &#8211;with-pdo-mysql=/usr/local/mysql-$PVERSION_MYSQL &#8211;with-pdo-sqlite &#8211;enable-sqlite-utf8 \<br />
  &#8211;enable-reflection \<br />
  &#8211;enable-session &#8211;with-mm \<br />
  &#8211;enable-shmop \<br />
  &#8211;enable-simplexml \<br />
  &#8211;enable-soap \<br />
  &#8211;enable-sockets \<br />
  &#8211;enable-spl \<br />
  &#8211;with-regex \<br />
  &#8211;enable-sysvmsg &#8211;enable-sysvsem &#8211;enable-sysvshm \<br />
  &#8211;enable-tokenizer \<br />
  &#8211;enable-xml &#8211;enable-xmlreader &#8211;with-xmlrpc &#8211;enable-xmlwriter &#8211;with-xsl \<br />
  &#8211;enable-zip \<br />
  \<br />
  &#8211;with-pear \<br />
  &#8211;enable-zend-multibyte
</p></blockquote>
<h3>Runtime configuration files</h3>
<p>Apache+mod_php: <a href='http://blog.a2o.si/wp-content/uploads/2009/06/httpd.conf.txt'>httpd.conf</a><br />
Apache+mod_php: <a href='http://blog.a2o.si/wp-content/uploads/2009/06/php.ini.txt'>php.ini</a><br />
Nginx+php-fpm: <a href='http://blog.a2o.si/wp-content/uploads/2009/06/nginx.conf.txt'>nginx.conf</a><br />
Nginx+php-fpm: <a href='http://blog.a2o.si/wp-content/uploads/2009/06/php-fpm.conf.txt'>php-fpm.conf</a><br />
Nginx+php-fpm: php.ini was functionally identical to the php.ini used by Apache+mod_php</p>
<h3>Results</h3>
<p>HelloWorld.php results:<br />
<div id="attachment_75" class="wp-caption aligncenter" style="width: 642px"><a href="http://blog.a2o.si/wp-content/uploads/2009/06/HelloWorld.php.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/HelloWorld.php.png" alt="Apache VS Nginx: HelloWorld.php" title="Apache VS Nginx: HelloWorld.php" width="632" height="265" class="size-full wp-image-75" /></a><p class="wp-caption-text">Apache VS Nginx: HelloWorld.php</p></div><br />
Here you are able to see an overhead which each PHP request imposes. Interesting and not unexpected  is a fact that Apache performs better at this test, much better. The reason here is that Apache has PHP processing &#8220;built-in&#8221; via mod_php module. On the other hand Nginx proxies PHP requests to another application server (php-fpm). The performance of Nginx in the graph above is roughly half of that of Apache, which can easily be explained with &#8220;two servers doing the work of one&#8221;. A reader must mind that here almost no PHP processing is done, a simple echo statement only.</p>
<p>&nbsp;<br />
HelloWorld.txt results:<br />
<div id="attachment_76" class="wp-caption aligncenter" style="width: 650px"><a href="http://blog.a2o.si/wp-content/uploads/2009/06/HelloWorld.txt.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/HelloWorld.txt.png" alt="Apache VS Nginx: HelloWorld.txt" title="Apache VS Nginx: HelloWorld.txt" width="640" height="294" class="size-full wp-image-76" /></a><p class="wp-caption-text">Apache VS Nginx: HelloWorld.txt</p></div><br />
At this test Apache starts to lag behind. Nginx perform better without keepalive feature, but with keepalive enabled it outperforms Apache by more than a factor of 2. This test is here only to demonstrate the overhead of static file serving.</p>
<p>&nbsp;<br />
100KB.txt results:<br />
<div id="attachment_73" class="wp-caption aligncenter" style="width: 645px"><a href="http://blog.a2o.si/wp-content/uploads/2009/06/100KB.txt.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/100KB.txt.png" alt="Apache VS Nginx: 100KB.txt" title="Apache VS Nginx: 100KB.txt" width="635" height="263" class="size-full wp-image-73" /></a><p class="wp-caption-text">Apache VS Nginx: 100KB.txt</p></div><br />
Here we start the real static file serving benchmark. With file size of 100KB we come closer to what one might call &#8220;real world benchmark&#8221;. Again we are able to demonstrate that Nginx without keepalive feature performs on-par with Apache with keepalive feature enabled. But Nginx with keepalive feature enabled outperforms Apache by factor of 2. The throughput we may calculate here is roughly around 1,2GB/s, but mind that all tests utilise loopback network interface.</p>
<p>&nbsp;<br />
1MB.txt results:<br />
<div id="attachment_72" class="wp-caption aligncenter" style="width: 648px"><a href="http://blog.a2o.si/wp-content/uploads/2009/06/1MB.txt.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/1MB.txt.png" alt="Apache VS Nginx: 1MB.txt" title="Apache VS Nginx: 1MB.txt" width="638" height="266" class="size-full wp-image-72" /></a><p class="wp-caption-text">Apache VS Nginx: 1MB.txt</p></div><br />
Again &#8220;real world static file serving benchmark&#8221;, yet this time with a file size of 1MB and without keepalive feature (keepalive does not matter anymore as majority of time is spent by transfering data and not by TCP overhead of establishing new connection).</p>
<p>&nbsp;<br />
Custom real world application performance comparison results:<br />
<div id="attachment_78" class="wp-caption alignnone" style="width: 651px"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/PHPapplication.png" alt="PHP application benchmark Apache+mod_php vs Nginx+php-fpm" title="Apache VS Nginx: PHP application" width="641" height="264" class="size-full wp-image-78" /><p class="wp-caption-text">PHP application benchmark Apache+mod_php vs Nginx+php-fpm</p></div><br />
Here you can see Nginx has a slight edge, but I must note that Apache had a .htaccess parsing enabled (AllowOverride All directive), a feature that Nginx is lacking. A drop in performance at the high concurrency levels has probably resulted from too few concurent database connections available to the system.</p>
<p>&nbsp;<br />
Apache HelloWorld.php VS HelloWorld.txt comparison results:<br />
<div id="attachment_74" class="wp-caption aligncenter" style="width: 648px"><a href="http://blog.a2o.si/wp-content/uploads/2009/06/ApachePHPvsTXT.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/ApachePHPvsTXT.png" alt="Apache VS Nginx: Apache PHP vs TXT" title="Apache VS Nginx: Apache PHP vs TXT" width="638" height="263" class="size-full wp-image-74" /></a><p class="wp-caption-text">Apache VS Nginx: Apache PHP vs TXT</p></div><br />
Note how close to the static file serving comes dynamic echoing the same content from PHP script.</p>
<p>&nbsp;<br />
Nginx HelloWorld.php VS HelloWorld.txt comparison results:<br />
<div id="attachment_77" class="wp-caption aligncenter" style="width: 648px"><a href="http://blog.a2o.si/wp-content/uploads/2009/06/NginxPHPvsTXT.png"><img src="http://blog.a2o.si/wp-content/uploads/2009/06/NginxPHPvsTXT.png" alt="Apache VS Nginx: Nginx PHP vs TXT" title="Apache VS Nginx: Nginx PHP vs TXT" width="638" height="263" class="size-full wp-image-77" /></a><p class="wp-caption-text">Apache VS Nginx: Nginx PHP vs TXT</p></div><br />
Nginx difference in static vs dynamic overhead is notably larger.</p>
<h3>Memory footprint</h3>
<p>If memory usage is of real importance to you, then you should seriously consider using Nginx. With nginx all the static file serving capabilities can be achieved by using only that many worker processes as there are CPU cores on your server. In the example above this means 8 cores and 8 worker processes for Nginx, no matter how many clients connect to it simultaneously. For PHP, there are 16 php-fpm workers alive in the example above (which is enought if you are not doing some blocking IO). When you sum this up you get a decently low memory usage.</p>
<p>On the other hand Apache (with prefork MPM, which is required by mod_php) creates as many processes as there are clients (up to the limit of MaxClients directive) and it does not matter whether clients are requesting static files or for PHP applications. So for 200 clients it will create 200 processes with embedded PHP, which gives far larger memory footprint than Nginx has.</p>
<h3>Conclusion or &#8220;should you switch from one to another?&#8221;</h3>
<p>Short answer: I do not know.<br />
Longer answers are here:</p>
<ol>
<li>If you host many websites and users utilise .htaccess files and change them frequently, then the answer is probably &#8220;no&#8221;. The cost of switching over to Nginx and converting all the configuration to new format usually reaches the cost of buying another server.</li>
<li>If you have single application on multiple servers and most of the processing power is not consumed by serving static file content, the answer is also probably &#8220;no&#8221;.</li>
<li>If you are mainly serving static content, the answer is obviously &#8220;yes&#8221;.</li>
<li>If you are creating a fresh system for webhosting solution, the answer is probably &#8220;yes&#8221;, with the assumption that users will not miss the .htaccess functionality or it will be provided by other means</li>
<li>If you are consolidating services with some virtualization technology, then answer is probably &#8220;yes&#8221;, as Nginx tends to have smaller memory footprint than Apache.</li>
<li>If you are looking towards Nginx as your PHP server optimization, look again, but not at Nginx, at your application code.</li>
</ol>
<p>I hope that this comparison helps you with your decision. If you have some questions, feel free to email me or post a comment below.</p>
<p>UPDATE 2009-06-25:<br />
The <em>ApacheBench</em> tool was invoked with the following command:</p>
<blockquote><p>
ab -n NREQ -c NCONC [-k] http://server.domain.com/bench/FileName<br />
NREQ is the number of requests:<br />
- HelloWorld.php: 500000<br />
- HelloWorld.txt:  500000<br />
- 100KB.txt:       500000<br />
- 1MB.txt:            50000<br />
- AppFront:            5000<br />
NCONC is the number of concurrent requests, as noted in the graphs.
</p></blockquote>
<p>Each test was repeaded 5 times and the average was calculated.<br />
Thanks to Sean Osh for requesting this info.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.a2o.si/2009/06/24/apache-mod_php-compared-to-nginx-php-fpm/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>HP DL380 G5 drive write cache (BBWC)</title>
		<link>http://blog.a2o.si/2009/06/19/hp-dl380-g5-drive-write-cache-bbwc/</link>
		<comments>http://blog.a2o.si/2009/06/19/hp-dl380-g5-drive-write-cache-bbwc/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 00:01:10 +0000</pubDate>
		<dc:creator>Boštjan Škufca</dc:creator>
				<category><![CDATA[Databases (RDBS)]]></category>
		<category><![CDATA[Filesystems]]></category>
		<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://blog.a2o.si/?p=41</guid>
		<description><![CDATA[In one of my previous articles I have written about tools that I use for benchmarking database performance and especially for discovering system bottlenecks. In this article I will show you how large impact on filesystem performance a drive write cache may have.
HP DL360 G4 server
HP and its line of DL servers is very respected [...]]]></description>
			<content:encoded><![CDATA[<p>In one of my previous articles I have written about tools that I use for benchmarking database performance and especially for discovering system bottlenecks. In this article I will show you how large impact on filesystem performance a drive write cache may have.</p>
<h3>HP DL360 G4 server</h3>
<p>HP and its line of DL servers is very respected amongst IT engineers. It is (at least by my experience) a reliable class of servers, well built, easy to maintain and comes with an excellent server management software called Integrated Lights-Out (ILO). DLs SCSI and SAS storage subsystem is usually controlled by controllers called Smart Array, which can be integrated onto the motherboard or not. Fresh HP customer gets all the nifty RAID levels to play with and is usually satisfied. But what fresh customer usually DOES NOT KNOW is that Smart Array write performance really sucks if write cache is not enabled. And to enable it, fresh user needs to install a special module with attached battery called BBWC. So, HP, if you are accidentally reading this, please do notify your customers about such things.</p>
<h4>HP DL380 G5 server</h4>
<p>This is another server where I conducted the benchmark and, unlike DL360 G4, already came with BBWC installed. To simulate absence of write cache I disabled it with command line tool <em>hpacucli</em> (HP Array Configuration Utility Command Line Interface).</p>
<h3>Benchmark metodology</h3>
<p>For this benchmark I used two tools from sql-bench suite which heavily stress filesystem with lots of file creations and deletions. These tools are <em>test-alter-table</em> and <em>test-create</em>. The former test is faster and only gives rough figure. The later creates and deletes around 50,000 MyISAM tables which results in 150,000 files created and deleted. I executed both benchmarks first without and then with write cache enabled.<br />
One of the machines (the DL380) was already in production, but it was benchmarked during the night when usage is negligible.</p>
<h3>Test systems</h3>
<p>HP DL360 G4</p>
<ul>
<li>Controller: Smart Array 6i</li>
<li>Filesystem: ufs</li>
<li>OS: FreeBSD 6.0</li>
<li>MySQL: mysql-5.0.41-freebsd6.0-i386</li>
</ul>
<p>HP DL380 G5</p>
<ul>
<li>Controller: Smart Array P400i</li>
<li>ext3 filesystem</li>
<li>OS: Slackware 12.2</li>
<li>MySQL: mysql-5.0.77 compiled from source</li>
</ul>
<h3>Results on HP DL380 G5</h3>
<p>Drive write cache DISABLED</p>
<blockquote><p>
Testing of ALTER TABLE<br />
Time for insert (1000) 0 wallclock secs<br />
( 0.02 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Time for alter_table_add (100): 17 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for create_index (8):  2 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for drop_index (8):  2 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for alter_table_drop (91): 16 wallclock secs ( 0.01 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.01 CPU)<br />
Total time: 37 wallclock secs ( 0.03 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.03 CPU)</p>
<p>Testing the speed of creating and dropping tables<br />
Time for create_MANY_tables (10000): 253 wallclock secs ( 0.26 usr  0.06 sys +  0.00 cusr  0.00 csys =  0.32 CPU)<br />
Time to select_group_when_MANY_tables (10000):  1 wallclock secs ( 0.09 usr  0.07 sys +  0.00 cusr  0.00 csys =  0.16 CPU)<br />
Time for drop_table_when_MANY_tables (10000):  1 wallclock secs ( 0.09 usr  0.03 sys +  0.00 cusr  0.00 csys =  0.12 CPU)<br />
Time for create+drop (10000): 259 wallclock secs ( 0.24 usr  0.18 sys +  0.00 cusr  0.00 csys =  0.42 CPU)<br />
Time for create_key+drop (10000): 255 wallclock secs ( 0.41 usr  0.11 sys +  0.00 cusr  0.00 csys =  0.52 CPU)<br />
Total time: 769 wallclock secs ( 1.09 usr  0.45 sys +  0.00 cusr  0.00 csys =  1.54 CPU)
</p></blockquote>
<p>Drive write cache ENABLED</p>
<blockquote><p>
Testing of ALTER TABLE<br />
Time for insert (1000) 0 wallclock secs ( 0.02 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Time for alter_table_add (100):  3 wallclock secs ( 0.01 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Time for create_index (8):  1 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for drop_index (8):  0 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for alter_table_drop (91):  4 wallclock secs ( 0.01 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.01 CPU)<br />
Total time:  8 wallclock secs ( 0.04 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.05 CPU)</p>
<p>Testing the speed of creating and dropping tables<br />
Time for create_MANY_tables (10000):  9 wallclock secs ( 0.34 usr  0.06 sys +  0.00 cusr  0.00 csys =  0.40 CPU)<br />
Time to select_group_when_MANY_tables (10000):  1 wallclock secs ( 0.06 usr  0.03 sys +  0.00 cusr  0.00 csys =  0.09 CPU)<br />
Time for drop_table_when_MANY_tables (10000):  1 wallclock secs ( 0.10 usr  0.04 sys +  0.00 cusr  0.00 csys =  0.14 CPU)<br />
Time for create+drop (10000):  9 wallclock secs ( 0.44 usr  0.10 sys +  0.00 cusr  0.00 csys =  0.54 CPU)<br />
Time for create_key+drop (10000): 10 wallclock secs ( 0.35 usr  0.10 sys +  0.00 cusr  0.00 csys =  0.45 CPU)<br />
Total time: 30 wallclock secs ( 1.29 usr  0.33 sys +  0.00 cusr  0.00 csys =  1.62 CPU)
</p></blockquote>
<p></p>
<table class="wptable rowstyle-alt" id="wptable-2" >
	<thead>
	<tr>
		<th class="sortable" style="width:200px" align="left">Drive write cache</th>
		<th class="sortable" style="width:70px" align="right">DISABLED</th>
		<th class="sortable" style="width:70px" align="right">ENABLED</th>
		<th class="sortable" style="width:200px" align="right">Relative difference</th>
	</tr>
	</thead>
	<tr>
		<td style="width:200px" align="left">sql-bench: test-alter-table</td>
		<td style="width:70px" align="right">37 s</td>
		<td style="width:70px" align="right">8 s</td>
		<td style="width:200px" align="right"><b>462%</b></td>
	</tr>
	<tr class="alt">
		<td style="width:200px" align="left">sql-bench: test-create</td>
		<td style="width:70px" align="right">769 s</td>
		<td style="width:70px" align="right">30 s</td>
		<td style="width:200px" align="right"><b>2563%</b></td>
	</tr>
</table><p>
</p>
<h3>Results on HP DL360 G4</h3>
<p>Drive write cache DISABLED</p>
<blockquote><p>
Testing of ALTER TABLE<br />
Time for insert (1000) 0 wallclock secs ( 0.02 usr  0.02 sys +  0.00 cusr  0.00 csys =  0.04 CPU)<br />
Time for alter_table_add (100): 33 wallclock secs ( 0.01 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Time for create_index (8):  4 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for drop_index (8):  3 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for alter_table_drop (91): 33 wallclock secs ( 0.01 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Total time: 75 wallclock secs ( 0.04 usr  0.03 sys +  0.00 cusr  0.00 csys =  0.07 CPU)</p>
<p>Testing the speed of creating and dropping tables<br />
Testing with 10000 tables and 10000 loop count<br />
Time for create_MANY_tables (10000): 1035 wallclock secs ( 1.27 usr  0.25 sys +  0.00 cusr  0.00 csys =  1.52 CPU)<br />
Time to select_group_when_MANY_tables (10000): 83 wallclock secs ( 0.63 usr  0.16 sys +  0.00 cusr  0.00 csys =  0.79 CPU)<br />
Time for drop_table_when_MANY_tables (10000): 493 wallclock secs ( 0.50 usr  0.19 sys +  0.00 cusr  0.00 csys =  0.69 CPU)<br />
Time for create+drop (10000): 958 wallclock secs ( 1.59 usr  0.38 sys +  0.00 cusr  0.00 csys =  1.97 CPU)<br />
(NOTICE: Could not wait for this test to finish, because machine needed to get back in production,)<br />
(thus I assume it to be around 900 seconds just to be on the safe side, probably would be more.)<br />
Total time calculated: around 3400 seconds
</p></blockquote>
<p>Drive write cache ENABLED</p>
<blockquote><p>
Testing of ALTER TABLE<br />
Time for insert (1000) 0 wallclock secs ( 0.02 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Time for alter_table_add (100):  8 wallclock secs ( 0.02 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Time for create_index (8):  1 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for drop_index (8):  1 wallclock secs ( 0.00 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.00 CPU)<br />
Time for alter_table_drop (91):  8 wallclock secs ( 0.01 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.02 CPU)<br />
Total time: 18 wallclock secs ( 0.05 usr  0.02 sys +  0.00 cusr  0.00 csys =  0.06 CPU)</p>
<p>Testing the speed of creating and dropping tables<br />
Time for create_MANY_tables (10000): 104 wallclock secs ( 1.07 usr  0.24 sys +  0.00 cusr  0.00 csys =  1.31 CPU)<br />
Time to select_group_when_MANY_tables (10000): 27 wallclock secs ( 0.48 usr  0.18 sys +  0.00 cusr  0.00 csys =  0.66 CPU)<br />
Time for drop_table_when_MANY_tables (10000): 53 wallclock secs ( 0.32 usr  0.09 sys +  0.00 cusr  0.00 csys =  0.41 CPU)<br />
Time for create+drop (10000): 143 wallclock secs ( 1.31 usr  0.30 sys +  0.00 cusr  0.00 csys =  1.62 CPU)<br />
Time for create_key+drop (10000): 164 wallclock secs ( 1.56 usr  0.36 sys +  0.00 cusr  0.00 csys =  1.92 CPU)<br />
Total time: 491 wallclock secs ( 4.74 usr  1.18 sys +  0.00 cusr  0.00 csys =  5.92 CPU)
</p></blockquote>
<p></p>
<table class="wptable rowstyle-alt" id="wptable-3" >
	<thead>
	<tr>
		<th class="sortable" style="width:200px" align="left">Drive write cache</th>
		<th class="sortable" style="width:70px" align="right">ABSENT</th>
		<th class="sortable" style="width:70px" align="right">ENABLED</th>
		<th class="sortable" style="width:200px" align="right">Relative difference</th>
	</tr>
	</thead>
	<tr>
		<td style="width:200px" align="left">sql-bench: test-alter-table</td>
		<td style="width:70px" align="right">75 s</td>
		<td style="width:70px" align="right">18 s</td>
		<td style="width:200px" align="right"><b>416%</b></td>
	</tr>
	<tr class="alt">
		<td style="width:200px" align="left">sql-bench: test-create</td>
		<td style="width:70px" align="right">3400 s</td>
		<td style="width:70px" align="right">491 s</td>
		<td style="width:200px" align="right"><b>692%</b></td>
	</tr>
</table><p>
</p>
<h3>Analysis</h3>
<p>The <em>test-alter-table</em> results seem fine, slightly over 400% increase in performance. But what bothers me is the <em>test-create</em> difference. I expected the HP DL360 G4 to improve more and execute this test below 100 seconds barier, heck, actually I expected it below 50 seconds. It is true that this machine uses different operating- and filesystem. But 500 seconds still seems too much to me, especially when HP DL380 G5 excells at 30 seconds. If someone know the answer, please drop it in comments.</p>
<h3>Conclusion</h3>
<p>I believe this article has clearly shown why one must conduct even such synthetic tests before deploying the systems to production environment. Furthermore even before the &#8220;real-world benchmarks&#8221; are conducted. The phrase &#8220;real-world benchmark&#8221; signifies a comparative benchmark of certain application on an existing production systems and on the ones that are in testing phase. It often happens that hardware is not upgraded for quite some time, which means that new hardware is few generations younger than the existing one. The new one is far more powerful and one easily misses some not-so-innocent bottleneck if &#8220;real-world benchmark&#8221; displays certain improvement. Thus, as I believe, newer systems MUST perform better than older ones in every synthetic benchmark (if the systems are comparable, of course), and only then we can start conducting &#8220;real-world benchmarks&#8221;.</p>
<h3>How did I discover this &#8220;issue&#8221;?</h3>
<p>It happened to me back in the 2004 that I deployed such a HP server to collocation facility and only later discovered that it was performing worse than some old test machine lying under my desk. After couple of hours of googling I assumed that the lack of BBWC was our problem. I had to order it and then remove the server from collocation because I also wanted to upgrade all the firmwares, just in case. On top of that, I still had to figure out how to install &#8216;hpacucli&#8217; on non-RedHat linux. After a long weekend the machine was back in production and never caused a single problem again.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.a2o.si/2009/06/19/hp-dl380-g5-drive-write-cache-bbwc/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MySQL sql-bench results</title>
		<link>http://blog.a2o.si/2009/06/16/mysql-sql-bench-results/</link>
		<comments>http://blog.a2o.si/2009/06/16/mysql-sql-bench-results/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 23:07:03 +0000</pubDate>
		<dc:creator>Boštjan Škufca</dc:creator>
				<category><![CDATA[Databases (RDBS)]]></category>

		<guid isPermaLink="false">http://blog.a2o.si/?p=27</guid>
		<description><![CDATA[This is a follow-up article to the MySQL Super Smack benchmark results. Results from sql-bench benchmark suite can easily pinpoint some of the potential system bottlenecks. I find it especially useful for discovering filesystem performance or &#8211; better &#8211; slowness.
Results
Total execution time is: 562 seconds

# run-all-tests
alter-table: Total time:  8 wallclock secs ( 0.02 usr [...]]]></description>
			<content:encoded><![CDATA[<p>This is a follow-up article to the <a href="http://blog.a2o.si/?p=4">MySQL Super Smack benchmark results</a>. Results from sql-bench benchmark suite can easily pinpoint some of the potential system bottlenecks. I find it especially useful for discovering filesystem performance or &#8211; better &#8211; slowness.</p>
<p><strong>Results</strong><br />
Total execution time is: <strong>562 seconds</strong></p>
<blockquote><p>
# run-all-tests<br />
alter-table: Total time:  8 wallclock secs ( 0.02 usr  0.01 sys +  0.00 cusr  0.00 csys =  0.03 CPU)<br />
ATIS: Total time:  2 wallclock secs ( 1.20 usr  0.09 sys +  0.00 cusr  0.00 csys =  1.29 CPU)<br />
big-tables: Total time:  5 wallclock secs ( 2.45 usr  0.08 sys +  0.00 cusr  0.00 csys =  2.53 CPU)<br />
connect: Total time: 50 wallclock secs (12.74 usr  4.50 sys +  0.00 cusr  0.00 csys = 17.24 CPU)<br />
create: Total time: 31 wallclock secs ( 1.20 usr  0.44 sys +  0.00 cusr  0.00 csys =  1.64 CPU)<br />
insert: Total time: 397 wallclock secs (97.95 usr 13.61 sys +  0.00 cusr  0.00 csys = 111.56 CPU)<br />
select: Total time: 44 wallclock secs ( 8.71 usr  0.88 sys +  0.00 cusr  0.00 csys =  9.59 CPU)<br />
transactions: Test skipped because the database doesn&#8217;t support transactions<br />
wisconsin: Total time:  3 wallclock secs ( 0.91 usr  0.23 sys +  0.00 cusr  0.00 csys =  1.14 CPU)<br />
TOTALS                               562.00  123.77   19.82  143.59 3425950
</p></blockquote>
<p>System specification can be found <a href="http://blog.a2o.si/?p=4">here</a>.</p>
<p><strong>ReiserFS vs others</strong><br />
In the age of Linux kernel 2.4.x we used ReiserFS v3 as the filesystem of choice. With the available options of ReiserFS (journal, performance), ext2 (stable but slow) and ext3 (probably stable, but not so speedy as ReiserFS) the choice was obvious. I skipped few years then and this year again tried using ReiserFS with linux 2.6.29.1 but it turned out to be even slower than ext2 was in the old days. Googling around for an answer gave some hints that ReiserFS has an issue with someting called BIG_KERNEL_LOCK on 2.6 kernels. I didn&#8217;t really investigate further, but went down the ext3 way.</p>
<p><strong>Comments on test-create</strong><br />
If test-create takes much more time than, say, 30-60 seconds, then you definitely have a problem with filesystem write performance. On HP DL360 and DL380 class of servers this correlates with the presence and activation of BBWC (Battery-Backed Write Cache enabler kit). Without BBWC and hence without write cache enabled, this test took more than 10 minutes to complete. Thus, if you are purchasing some new HP servers, be sure that you also order BBWCs.</p>
<p><strong>Question about test-insert</strong><br />
Looking at the test times, this test-insert result is really standing out. Again, I do not have any other data to compare it to, but somewhere deep down in my memory I seem to remember that the total time for all the tests was around 300 seconds. This obviously means that this test-insert result is the bad guy here. Can someone comment on this result, or paste in the comments his own? Thanks.</p>
<p><strong>Feedback</strong><br />
If you have any questions, recommendations or benchmark results to compare, do not hesitate to leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.a2o.si/2009/06/16/mysql-sql-bench-results/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Super Smack database benchmark results</title>
		<link>http://blog.a2o.si/2009/06/16/mysql-super-smack-database-benchmark-results/</link>
		<comments>http://blog.a2o.si/2009/06/16/mysql-super-smack-database-benchmark-results/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 22:12:45 +0000</pubDate>
		<dc:creator>Boštjan Škufca</dc:creator>
				<category><![CDATA[Databases (RDBS)]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[hp dl380]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[results]]></category>
		<category><![CDATA[super smack]]></category>

		<guid isPermaLink="false">http://blog.a2o.si/?p=4</guid>
		<description><![CDATA[After a couple of years away in academic environment, I got myself back into the business of system administration (or as I prefer to call it, system engineering), Linux/BSD system administration to be precise. Of course, all the old (and precious) notes and data were gone, so I had to start from scratch. I was [...]]]></description>
			<content:encoded><![CDATA[<p>After a couple of years away in academic environment, I got myself back into the business of system administration (or as I prefer to call it, system engineering), Linux/BSD system administration to be precise. Of course, all the old (and precious) notes and data were gone, so I had to start from scratch. I was given a task to put together a scalable system of web servers. At certain point I started to benchmark the systems and I have realised that I had almost no data to compare the results to. Therefore I decided to share these results with the world and in the same manner make it available for me in the future. They are intended as a reference point if you want to know how much performance can you squeeze out of certain hardware/software.</p>
<p>Today I am starting with MySQL, the database of choice for many web developers.</p>
<p>For benchmarking MySQL performance, I primarily use three tools:</p>
<ol>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/mysql-benchmarks.html">The MySQL benchmark suite</a>,</li>
<li><a title="Super Smack" href="http://vegan.net/tony/supersmack/">Super Smack</a> and</li>
<li>some custom applications for real world tests.</li>
</ol>
<p>As it is commonly known, first two items from the list above are not what one might call &#8220;real world benchmark suites&#8221;. But they are very fine tools for discovering system bottlenecks and obvious configuration errors. Below follow benchmark commands and results with complete (relevant) setup description. Enjoy!</p>
<p><strong>Results for select-key</strong><br />
Queries per second: <strong>166541</strong></p>
<blockquote><p>
cd /usr/share/smacks &#038;&#038;<br />
super-smack select-key.smack 32 100000</p>
<p>Query Barrel Report for client smacker1<br />
connect: max=34ms  min=0ms avg= 14ms from 32 clients<br />
Query_type	num_queries	max_time	min_time	q_per_s<br />
select_index	6400000	0	0	166541.80
</p></blockquote>
<p><strong>Results for update-key</strong><br />
Queries per second: <strong>9225</strong></p>
<blockquote><p>
cd /usr/share/smacks &#038;&#038;<br />
super-smack update-select.smack 32 10000</p>
<p>Query Barrel Report for client smacker<br />
connect: max=0ms  min=0ms avg= 0ms from 32 clients<br />
Query_type	num_queries	max_time	min_time	q_per_s<br />
select_index	320000	2	0	9225.27<br />
update_index	320000	2	0	9225.27
</p></blockquote>
<p><strong>Hardware</strong></p>
<ul>
<li>HP DL380 g5</li>
<li>2x Intel E5420 Xeon (4 cores @ 2.5GHz each)</li>
<li>8GB ECC RAM</li>
<li>2x 147 SAS 10k drives in hardware RAID-1 configuration</li>
<li>Write cache enabled for Smart Array P400i</li>
</ul>
<p><strong>Software</strong></p>
<ul>
<li>Slackware 12.2</li>
<li>Ext3 filesystem</li>
<li>Linux kernel version 2.4.29.1</li>
<li>Super Smack 1.3, compiled from source</li>
<li>MySQL version 5.0.77, compiled from source with configure line:<br />
<blockquote><p>
./configure &#8211;prefix=/usr/local/$PDIR \<br />
  &#8211;with-charset=utf8 &#8211;with-collation=utf8_general_ci \<br />
  &#8211;with-unix-socket-path=/var/mysql/run/mysql.sock \<br />
  &#8211;with-mysqld-user=mysql \<br />
  &#8211;with-openssl=/usr/local/openssl-0.9.8k
</p></blockquote>
</li>
</ul>
<p><strong>/etc/my.cnf</strong></p>
<blockquote><p>
[client]<br />
socket		 = /var/mysql/run/mysql.sock</p>
<p>[mysqld]<br />
user             = mysql<br />
basedir          = /usr/local/mysql<br />
pid-file         = /var/mysql/run/mysqld.pid<br />
socket           = /var/mysql/run/mysql.sock<br />
datadir          = /var/mysql/data<br />
log-error        = /var/mysql/log/mysql_error.log<br />
log-slow-queries = /var/mysql/log/mysql_slow_query.log</p>
<p>ssl<br />
ssl-cert = /etc/ssl/certs/_default.cert<br />
ssl-key  = /etc/ssl/certs/_default.key</p>
<p>key_buffer              = 256M<br />
max_allowed_packet      = 32M<br />
table_cache             = 256<br />
sort_buffer_size        = 2M<br />
read_buffer_size        = 4M<br />
read_rnd_buffer_size    = 8M<br />
myisam_sort_buffer_size = 64M<br />
net_buffer_length       = 2K<br />
thread_stack            = 128K<br />
thread_cache_size       = 16K<br />
thread_concurrency      = 8<br />
query_cache_size        = 32M<br />
max_join_size           = 4294967295</p>
<p>innodb_data_home_dir            = /var/mysql/data<br />
innodb_data_file_path           = ibdata1:10M:autoextend<br />
innodb_log_group_home_dir       = /var/mysql/data<br />
innodb_log_arch_dir             = /var/mysql/data<br />
innodb_buffer_pool_size         = 16M<br />
innodb_additional_mem_pool_size = 2M<br />
innodb_log_file_size            = 5M<br />
innodb_log_buffer_size          = 8M<br />
innodb_flush_log_at_trx_commit  = 1<br />
innodb_lock_wait_timeout        = 50</p>
<p>[mysqldump]<br />
quick<br />
max_allowed_packet = 32M</p>
<p>[mysql]<br />
no-auto-rehash</p>
<p>[isamchk]<br />
key_buffer       = 128M<br />
sort_buffer_size = 128M<br />
read_buffer      = 2M<br />
write_buffer     = 2M</p>
<p>[myisamchk]<br />
key_buffer       = 128M<br />
sort_buffer_size = 128M<br />
read_buffer      = 2M<br />
write_buffer     = 2M</p>
<p>[mysqlhotcopy]<br />
interactive-timeout
</p></blockquote>
<p>And also the results of sql-bench suite are <a href="http://blog.a2o.si/?p=4">here</a>.</p>
<p><strong>Feedback</strong><br />
If you have any questions, recommendations or benchmark results to compare, do not hesitate to leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.a2o.si/2009/06/16/mysql-super-smack-database-benchmark-results/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
