<?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>FewBar.com - Make it good &#187; performance</title>
	<atom:link href="http://fewbar.com/tag/performance/feed/" rel="self" type="application/rss+xml" />
	<link>http://fewbar.com</link>
	<description>Technology, life, and mischief, not in that order</description>
	<lastBuildDate>Fri, 23 Dec 2011 01:41:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Where did those numbers come from?</title>
		<link>http://fewbar.com/2010/06/cassandra-where-did-those-numbers-come-from/</link>
		<comments>http://fewbar.com/2010/06/cassandra-where-did-those-numbers-come-from/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 06:22:17 +0000</pubDate>
		<dc:creator>clint</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[velocityconf]]></category>

		<guid isPermaLink="false">http://fewbar.com/?p=216</guid>
		<description><![CDATA[Did you ever hear a claim that sounded too bad to be true? So this past Tuesday at Velocity 2010, Brett Piatt gave a workshop on the Cassandra database. I was seated in the audience and quite interested in everything he had to say about running Cassandra, given that I&#8217;ve been working on adding Cassandra [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://fewbar.com.s3.amazonaws.com/wp-content/uploads/2010/06/snake-oil1.jpg"><img class="alignleft size-full wp-image-218" title="snake-oil1" src="http://fewbar.com.s3.amazonaws.com/wp-content/uploads/2010/06/snake-oil1.jpg" alt="" width="188" height="427" /></a><br />
Did you ever hear a claim that sounded too <strong>bad</strong> to be true?<br />
So this past Tuesday at Velocity 2010, Brett Piatt gave a <a href="http://en.oreilly.com/velocity2010/public/schedule/detail/14433">workshop on the Cassandra database</a>. I was seated in the audience and quite interested in everything he had to say about running Cassandra, given that I&#8217;ve been working on <a href="https://blueprints.launchpad.net/ubuntu/+spec/server-maverick-cloud-datastores">adding Cassandra and other scalable data stores to Ubuntu</a>.</p>
<p>Then at one point, up popped a table that made me curious.<br />
<span id="more-216"></span><br />
It looked a lot like this:</p>
<p>With a 50GB table</p>
<table>
<thead>
<tr>
<td></td>
<td>MySQL</td>
<td>Cassandra</td>
</tr>
</thead>
<tbody>
<tr>
<td>writes</td>
<td>300ms</td>
<td>0.19ms</td>
</tr>
<tr>
<td>reads</td>
<td>250ms</td>
<td>1.6ms</td>
</tr>
</tbody>
</table>
<p>Actually it looked exactly like that, because it was copied from <a href="http://webcache.googleusercontent.com/search?sourceid=chrome&amp;ie=UTF-8&amp;q=cache:http://wiki.apache.org/cassandra/ArchitectureOverview">this page</a> that is, as of this point,  only available in its original form in google cache.</p>
<p>The page linked has *no* explanation of this table. Its basically just &#8220;OH DAAAAMN MySQL you got pwned&#8221;. But seriously, WTF?</p>
<p>I asked Brett where those numbers came from, and whether we could run the tests ourselves to compare our write performance to Cassandra&#8217;s <em>I don&#8217;t mean to say &#8220;our write performance&#8221; as in MySQL&#8217;s, as this statement implies, but rather ours to the write performance of the Cassandra team&#8217;s</em>. Brett claimed ignorance and just referred to the URL of the architecture page.</p>
<p>Ok fair enough. I figured I should investigate more ,so I asked on #cassandra on freenode. People pointed me to various other slide decks with the same table in them, but none with any explanation.</p>
<p>At some point, somebody rightfully recognized that having these numbers with no plausible explanation is ridiculous, and removed them from the site. Another person did in fact rightfully recognize why this may be the case.</p>
<p>Basically with a 50G table, assuming small records, you will have *a giant* B-Tree for the primary key of that table (assuming you have one) will take 30+ disk seeks to update. That means that at 10ms (meaning, HORRIBLE) per seek, we&#8217;ll take 300ms to write. This is contrasted to Cassandra which can just append, requiring at most one seek.</p>
<p>So anyway, Cassandra team, thanks for the explanation, and kudos for righting this problem. Unfortunately the misinformation <a href="http://theagileadmin.com/2010/06/22/velocity-2010-cassandra-workshop/">tends to be viral</a>, so I&#8217;m sure there are people out there who will forever believe that MySQL takes 300ms to update a 50G table.</p>
]]></content:encoded>
			<wfw:commentRss>http://fewbar.com/2010/06/cassandra-where-did-those-numbers-come-from/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gearman K.O.&#8217;s mysql to solr replication</title>
		<link>http://fewbar.com/2010/03/gearman-replicate-mysql-to-solr/</link>
		<comments>http://fewbar.com/2010/03/gearman-replicate-mysql-to-solr/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 05:47:36 +0000</pubDate>
		<dc:creator>clint</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://fewbar.com/?p=154</guid>
		<description><![CDATA[Ding ding ding.. in this corner, wearing black shorts and a giant schema, we have over 11 million records in MySQL with a complex set of rules governing which must be searchable and which must not be. And in that corner, we have the contender, a kid from the back streets, outweighed and out reached [...]]]></description>
			<content:encoded><![CDATA[<p>Ding ding ding.. in this corner, wearing black shorts and a giant schema, we have over 11 million records in MySQL with a complex set of rules governing which must be searchable and which must not be. And in that corner, we have the contender, a kid from the back streets, outweighed and out reached by all his opponents, but still victorious in the queue shootout, with just open source, and 12 patch releases.. written in C, its <b><a href="http://gearman.org">gearman</a></b>!</p>
<p><a href="http://fewbar.com.s3.amazonaws.com/wp-content/uploads/2010/03/ko-mike-tyson.png"><img src="http://fewbar.com.s3.amazonaws.com/wp-content/uploads/2010/03/ko-mike-tyson.png" alt="" title="ko-mike-tyson" width="500" height="437" class="alignnone size-full wp-image-155" /></a><br />
<span id="more-154"></span></p>
<p>I&#8217;m pretty excited today, as I&#8217;m preparing to go live with the first real, high load application of Gearman that I&#8217;ve written. What is it you say? Well it is a simple trigger based replicator from mysql to <a href="http://lucene.apache.org/solr/">SOLR</a>.</p>
<p>I should say (because I know some of my colleagues read this blog) that I don&#8217;t actually believe in this design. Replication using triggers seems fraught with danger. It totally makes sense if you have a giant application and can&#8217;t track down everywhere that a table is changed. However, if your app is simple and properly abstracted, hopefully you know the 1 or 2 places that write to the table.</p>
<p>I should also say that I really can&#8217;t reveal all of the details. The general idea is pretty simple. Basically we have a trigger that dumps a primary key into gearman via the <a href="https://launchpad.net/gearman-mysql-udf">gearman MySQL UDFs</a>. The idea is just to tell a gearman worker &#8220;look at this record in that table&#8221;.</p>
<p>Once the worker picks it up, it applies some logic to the record.. &#8220;should this be searchable or not&#8221;. If the answer is yes it should be searchable, the worker pushes the record into SOLR. If not, the worker will make sure it is not in solr.</p>
<p>This at least is pretty simple. The end result is a system where we can rebuild the search index in parallel using multiple CPU&#8217;s (thank you to solr/lucene for being able to update indexes concurrently and efficiently btw). This is done by pushing all of the records in the table into the queue at once.</p>
<p>Anyway, gearmand is performing like a champ, libgearman and the gearman pecl module are doing great. I&#8217;m just really happy to see gearman rolled out in production, as I really do think it has that nice mix of simplicity and performance. I love the commandline client which makes it easy to write scripts to inject things into queues, or query workers.  This allows me to access a worker like this:</p>
<p><code>$ gearman -h gearmanbox -f all_workers -s<br />
Known Workers: 11</p>
<p>boxname_RealTimeUpdate_Queue_TriggerWorker_1 jobs=627366,restarts=0,memory_MB=4.27,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13311 jobs=304134,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:58 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13306 jobs=606126,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13314 jobs=576714,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13342 jobs=294846,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13347 jobs=376998,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13359 jobs=470508,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:58 -0700<br />
boxname_RealTimeUpdate_Queue_Subject_13364 jobs=403182,restarts=0,memory_MB=7.03,lastcheckin=Tue, 23 Mar 2010 22:37:58 -0700<br />
boxname_RealTimeUpdate_Property_SolrPublish_ jobs=219630,restarts=0,memory_MB=6.19,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Queue_TriggerWorker_2 jobs=393642,restarts=0,memory_MB=4.27,lastcheckin=Tue, 23 Mar 2010 22:37:59 -0700<br />
boxname_RealTimeUpdate_Property_SolrBatchPub jobs=6,restarts=0,memory_MB=6.23,lastcheckin=Tue, 23 Mar 2010 22:37:28 -0700</code></p>
<p>Brilliant.. no need for html or HTTP.. just a nice simple commandline interface.</p>
<p>I think gearman still has a ways to go. I&#8217;d really like to see some more administration added to it. Deleting empty queues and quickly flushing all queues without restarting gearmand would be nice to haves. We&#8217;ll see what happens going forward, but for not, thanks so much to the gearman team (especially Eric Day who showed me gearman, and Brian Aker for pushing hard to release v0.12).</p>
<p>w00t!</p>
]]></content:encoded>
			<wfw:commentRss>http://fewbar.com/2010/03/gearman-replicate-mysql-to-solr/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Can more queries equal a healthier MySQL server?</title>
		<link>http://fewbar.com/2008/08/innodb-concurrency-problems-on-multi-core-boxes-possibly-a-thing-of-the-past/</link>
		<comments>http://fewbar.com/2008/08/innodb-concurrency-problems-on-multi-core-boxes-possibly-a-thing-of-the-past/#comments</comments>
		<pubDate>Sat, 30 Aug 2008 06:21:34 +0000</pubDate>
		<dc:creator>clint</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://fewbar.com/?p=14</guid>
		<description><![CDATA[This week was an ugly one for my monster database servers. It should have been triumphant, but oddly enough, I think it shows how prone to mistuning InnoDB on MySQL 5.0 is with multiple cores. This server is a multi-core, high concurrency server. The application has been designed a little bit naively in that it [...]]]></description>
			<content:encoded><![CDATA[<p>This week was an ugly one for my monster database servers. It should have been triumphant, but oddly enough, I think it shows how prone to mistuning InnoDB on MySQL 5.0 is with multiple cores.</p>
<p>This server is a multi-core, high concurrency server. The application has been designed a little bit naively in that it just throws almost all queries at the main db server. Several bits have been designed to scale by not doing that, but unfortunately, huge amounts of functionality were built around those apps to prevent them from scaling.</p>
<p>As a result, we&#8217;ve had to scale up the central database server and its redundant systems significantly. We started with the Proliant DL380 G4 with two Xeon 3.4Ghz CPU&#8217;s and 12GB of RAM, and plenty of disks in an external RAID. As more traffic was added, we moved up to the DL580 servers with 4 Xeon 3.4Ghz and 64GB of RAM. This worked well, but still more traffic, and more data, was coming and the app wasn&#8217;t ready to change significantly. We finally landed on the latest DL580 server, with 1GB of total battery backed write cache, 14 SAS disks, 128GB of RAM, and two quad core Xeon CPU&#8217;s.<br />
<span id="more-14"></span><br />
Some things got better. Writes were now incredibly fast. The server was churning out 1000 queries per second easily. Sometimes during peak times, query response time would suffer, but ultimately, the box was keeping up and performing well. <a href="http://fewbar.com/2008/07/mysql-query-cache-scales-like-a-286-with-turbo-off/">Especially after we turned of query caching</a>. After this week though, I wonder how much of the problem was query caching&#8230; more later.</p>
<p>Anyway, whenever the server would need to have maintenance, some high traffic applications would suffer needlessly for their need of rarely changing data (memcached was out of the question for the complexity and &#8220;realtime&#8221; nature of this data). So we setup a selective replication fanout onto multiple boxes and pointed these apps at that cluster for these queries.</p>
<p>Well the next day, without all of these tiny queries pounding on it, the database server had horrible problems. 400 threads stacked up inside InnoDB &#8220;Waiting for InnoDB queue&#8221;. System resources were fine, but it was clear, InnoDB was having trouble. Queries that normally take 0.75 seconds were taking 300+ seconds, or just never completing. I knew there was real trouble, when killing the thread would result in it just changing state to &#8220;Killed&#8221;, but never dying. Based on what I&#8217;d read in High Performance MySQL, and <a href="http://www.mysqlperformanceblog.com/2006/06/05/innodb-thread-concurrency/">articles like this one</a>, I tried twiddling with innodb_thread_concurrency, innodb_concurrency_tickets, and innodb_thread_sleep_delay. None of them seemed to help, though innodb_thread_concurrency set to a value of about half the CPU cores seemed to delay the problems.</p>
<p>I noticed that we were running MySQL v5.0.51a still. We had planned an upgrade to 5.0.67, which was just recently released, but hadn&#8217;t gotten there yet. I went ahead and upgraded one of the boxes to it, and failed over to it. Instantly things were more healthy, and the health seemed to stay for hours, without any more InnoDB freakouts.</p>
<p>After some research, it would seem that between 5.0.51a and 5.0.67, a lot of really big fixes were made to InnoDB to help it scale up on multi-core machines. The box has been healthy for a couple of days, though there&#8217;s still a lot of work to do removing query load from the server.</p>
<p>But why would a _reduction_ in queries cause concurrency problems? I have a theory, but no real ideas on how to test it.</p>
<p>Before, we were doing 1000 queries per second. Things were healthy. We removed about 400 queries per second from that. These 400 queries were basically instantaneous.. often times returning no results at all and reading from tables and indexes completely stored in the innodb_buffer_pool. But, with query cache turned off, they were still being processed fully by InnoDB. When we removed these tiny queries from the queue imposed by innodb_thread_concurrency, I think we removed the equivalent of spin waits from the queue. These tiny, easy queries were just hard enough to process, to prevent a lot of bigger queries from hitting the queue at the same time. Thats why reducing innodb_thread_concurrency to 4 helped a bit.. with only 4 threads vying for mutexes and CPU resources constantly, InnoDB was able to (sort of) keep up.</p>
<p>My final bit of evidence for this is that we actually, I think, had this problem before with the <a href="http://fewbar.com/2008/07/mysql-query-cache-scales-like-a-286-with-turbo-off/">aforementioned article</a>. Turning off the query cache moved these tiny queries out of the query cache, and into the InnoDB queue, providing the needed pseudo-spin-waits to prevent it from locking in on itself.</p>
<p>I have to wonder if raising innodb_sync_spin_loops to something ridiculously high, like 50000, would have the same effect. Unfortunately, its very hard to test this without dedicating a lot of time to it.</p>
<p>So, in this case, it would seem that more work can, in fact, make the server healthier.</p>
]]></content:encoded>
			<wfw:commentRss>http://fewbar.com/2008/08/innodb-concurrency-problems-on-multi-core-boxes-possibly-a-thing-of-the-past/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.155 seconds -->

