<?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>codeaholics.org</title>
	<atom:link href="http://blog.codeaholics.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.codeaholics.org</link>
	<description>addicted to codeahol since 1985</description>
	<lastBuildDate>Thu, 13 Mar 2014 21:53:11 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>Giving Docker/LXC containers a routable IP address</title>
		<link>http://blog.codeaholics.org/2013/giving-dockerlxc-containers-a-routable-ip-address/</link>
		<comments>http://blog.codeaholics.org/2013/giving-dockerlxc-containers-a-routable-ip-address/#comments</comments>
		<pubDate>Wed, 02 Oct 2013 22:20:32 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=281</guid>
		<description><![CDATA[At work, we are evaluating Docker as part of our &#8220;epic next generation deployment platform&#8221;. One of the requirements that our operations team has given us is that our containers have &#8220;identity&#8221; by virtue of their IP address. In this &#8230; <a href="http://blog.codeaholics.org/2013/giving-dockerlxc-containers-a-routable-ip-address/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>At work, we are evaluating <a href="http://docker.io">Docker</a> as part of our &#8220;epic next generation deployment platform&#8221;. One of the requirements that our operations team has given us is that our containers have &#8220;identity&#8221; by virtue of their IP address. In this post, I will describe how we achieved this.</p>
<p>But first, let me explain that a little. Docker (as of version 0.6.3) has 2 networking modes. One which goes slightly further that what full virtualisation platforms would typically call &#8220;host only&#8221;, and no networking at all (if you can call that a mode!) In &#8220;host only&#8221; mode, the &#8220;host&#8221; (that is, the server running the container) can communicate with the software inside the container very easily. However, accessing the container from beyond the host (say, a client &#8211; shock! horror!) isn&#8217;t possible.</p>
<p>As mentioned, Docker goes a little bit further by providing &#8220;port forwarding&#8221; via iptables/NAT on the host. It selects a &#8220;random&#8221; port, say 49153 and adds iptables rules such that if you attempt to access this port on the host&#8217;s IP address, you will actually reach the container. This is fine, until you stop the container and restart it. In this case, your container will get a new port. Or, if you restart it on a different host, it will get a new port AND IP address.</p>
<p>One way to address this is via a service discovery mechanism, whereby when the service comes up it registers itself with some kind of well-known directory and clients can discover the service&#8217;s location by looking it up in the directory. This has its own problems &#8211; not least of which is that the service inside the container has no way of knowing what the IP address of the host it&#8217;s running on is, and no way of knowing which port Docker has selected to forward to it!</p>
<p>So, back to the problem in hand. Our ops guys want to treat each container as a well-known service in its own right and give it a proper, routable IP address. This is very much like what a virtualisation platform would call &#8220;bridged mode&#8221; networking. In my opinion, this is a very sensible choice.</p>
<p>Here&#8217;s how I achieved this goal:</p>
<h2>Defining a new virtual interface</h2>
<p>In order to have a separate IP address from the host, we will need a new virtual interface. I chose to use a <code>macvlan</code> type interface so that it could have its own MAC address and therefore receive an IP by DHCP if required.</p>
<p><code>ip link add virtual0 link eth0 type macvlan mode bridge</code></p>
<p>This creates a new virtual interface called <code>virtual0</code>. You will need a separate interface for each container. I am using bridged mode as it means container-to-container traffic doesn&#8217;t travel across the wire to the switch/router and back.</p>
<p>If you need a fixed MAC address &#8211; perhaps because you want a fixed IP address and you achieve this by putting a fixed MAC-to-IP mapping in your DHCP server &#8211; you need to add the following to the end of the line:</p>
<p><code>ip link add ... address 00:11:22:33:44:55</code></p>
<p>(substitute your own MAC address!)</p>
<p>If you do not do this, the kernel will randomly generate a MAC for you.</p>
<h2>Giving the interface an IP address</h2>
<p>If you want a fixed IP address and you&#8217;re happy to statically configure it:</p>
<p><code>ip address add 10.10.10.88/24 broadcast 10.10.10.255 dev virtual0</code></p>
<p>(substitute your own IP address, subnet mask and broadcast address)</p>
<p>If, however, you need to use DHCP to get an address (development environment, for example):</p>
<p><code>dhclient virtual0</code></p>
<p>This will start the DHCP client managing just this one interface and leave it running in the background dealing with lease renewals, etc. Once you&#8217;re ready to tear down the container and networking, you need to remember to kill the DHCP client, or, better yet:</p>
<p><code>dhclient -d -r virtual0</code></p>
<p>will locate the existing instance of the client for that interface, tell it to properly release the DHCP lease, and then exit.</p>
<p>Finally, bring the interface up:</p>
<p><code>ip link set virtual0 up</code></p>
<h2>Find the container&#8217;s internal IP address</h2>
<p>If you haven&#8217;t done so now, start your container as a daemon.</p>
<p>Use <code>docker inspect &lt;container id&gt;</code> to find the internal IP address under NetworkSettings/IPAddress.</p>
<h2>Setting up inbound routing/NAT</h2>
<p>Create a chain for the inbound routing rules for this container. I prefer to use a separate chain for each container as it makes cleaning up easier.</p>
<p><code>iptables -t nat -N BRIDGE-VIRTUAL0  # some unique name for the iptables chain for this container</code></p>
<p>Now, send all incoming traffic to this chain. We add a rule in <code>PREROUTING</code> which will match traffic coming in from outside, and a rule in <code>OUTPUT</code> which will match traffic generated on the host. Here, <code>&lt;container external IP&gt;</code> is the routable IP allocated statically or via DHCP to the <code>virtual0</code> interface.</p>
<p><code>iptables -t nat -A PREROUTING -p all -d &lt;container external IP&gt; -j BRIDGE-VIRTUAL0<br />
iptables -t nat -A OUTPUT -p all -d &lt;container external IP&gt; -j BRIDGE-VIRTUAL0</code></p>
<p>Finally, NAT all inbound traffic to the container. Here, <code>&lt;container internal IP&gt;</code> is the internal address of the container as discovered using the <code>docker inspect</code> command.</p>
<p><code>iptables -t nat -A BRIDGE-VIRTUAL0 -p all -j DNAT --to-destination &lt;container internal IP&gt;</code></p>
<p>This particular rule will forward inbound traffic for any port on the external IP to the same port on the internal IP &#8211; effectively exposing anything that the container exposes to the outside world. As an alternative, you can expose individual ports like so:</p>
<p><code>iptables -t nat -A BRIDGE-VIRTUAL0 -p all -m tcp --dport 80 -j DNAT --to-destination &lt;container internal IP&gt;:8080</code></p>
<p>In this example, we forward any traffic hitting port 80 on our external IP to port 8080 on the internal IP &#8211; effectively exposing a web server on port 8080 inside the container as port 80 on the external IP. Nice tidy URLs that don&#8217;t have port numbers on. Neat, huh? You can even map multiple external ports to the same internal port by using multiple rules if you wish.</p>
<h2>Setting up outbound NAT</h2>
<p>What we have so far works, but if the container initiates any outbound requests, they will appear (by virtual of Docker&#8217;s default <code>MASQUERADE</code> rule) to come from the hosts own IP. This may be fine depending on your circumstances. But it probably won&#8217;t play well if you want to get firewalls involved anywhere, and it might be a nuisance if you&#8217;re using <code>netstat</code> or similar to diagnose where all the incoming connections to a heavily loaded server are coming from.</p>
<p>So&#8230; we&#8217;ll add &#8220;source NAT&#8221; into the equation so that outbound connections from the container come from its own IP:</p>
<p><code>iptables -t nat -I POSTROUTING -p all -s &lt;container internal IP&gt; -j SNAT --to-source &lt;container external IP&gt;</code></p>
<p>This rule says any traffic we&#8217;re routing outbound which has a source address of the containers internal IP should have the source address changed to the containers external IP.</p>
<p><strong>Note</strong> that we use <code>-I</code> (not <code>-A</code>) to ensure our rule goes ahead of Docker&#8217;s default <code>MASQUERADE</code> rule.</p>
<h2>And finally</h2>
<p>This all worked fine when I set it up at home, and then failed in the office. It turns out that it fails when you&#8217;re on a routed network (my network at home is a simple, flat network) and you try and reach your container from a different subnet. To cut a long story short, you need to disable &#8220;reverse path filtering&#8221;!</p>
<p><code>echo 2 &gt; /proc/sys/net/ipv4/conf/eth0/rp_filter<br />
echo 2 &gt; /proc/sys/net/ipv4/conf/virtual0/rp_filter</code></p>
<p>For more information about this, see <a href="http://serverfault.com/questions/464045/how-to-make-iptables-dnat-work-with-macvlan">this ServerFault question</a>, this <a href="http://nrocco.github.io/2013/04/13/disable-rp-filter.html">article</a> and this <a href="http://www.slashroot.in/linux-kernel-rpfilter-settings-reverse-path-filtering">article</a> (linked from the previous one).</p>
<h2>Summary</h2>
<p>There&#8217;s a lot of information in this post, but in summary what we&#8217;ve done is:</p>
<ol>
<li>Create a new virtual interface for the container</li>
<li>Given the virtual interface an IP address either statically or using DHCP</li>
<li>Used iptables to set up inbound routing to allow the container to be reached via its external/routable IP from both the host and the network beyond the host</li>
<li>Optionally forwarded (and even more optionally, aliased) only specific inbound ports</li>
<li>Set up source NAT to rewrite outbound traffic from the container to use the correct external IP</li>
<li>Given the kernel a bit of a helping hand to understand that we&#8217;re not terrorists and it&#8217;s safe to &#8220;do the right thing&#8221; with our slightly odd-looking traffic</li>
</ol>
<p>The first 5 steps of this took me about 20 minutes to figure out. Step 6 took me 3 days, the help of several network engineers, one extremely patient ops guy and no small amount of blind luck!</p>
<p>I hope having it all written down in one place will be helpful to others.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2013/giving-dockerlxc-containers-a-routable-ip-address/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>Redis memory optimisation</title>
		<link>http://blog.codeaholics.org/2013/redis-memory-optimisation/</link>
		<comments>http://blog.codeaholics.org/2013/redis-memory-optimisation/#respond</comments>
		<pubDate>Thu, 15 Aug 2013 15:51:23 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Redis]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=266</guid>
		<description><![CDATA[According to Alexa, my employer&#8217;s web site is the 13th most popular web site in the UK, the 66th most popular in the US and the 127th most popular in the world. At least it is today. Not too shabby, &#8230; <a href="http://blog.codeaholics.org/2013/redis-memory-optimisation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>According to Alexa, my employer&#8217;s <a href="http://www.dailymail.co.uk/" title="MailOnline" target="_blank">web site</a> is the 13th most popular web site in the UK, the 66th most popular in the US and the 127th most popular in the world. At least it is today. Not too shabby, eh?</p>
<p>So real-time analytics is fun. At our peak time (UK lunch time) we get in the region of 500 views per second on our article pages. This doesn&#8217;t include the various index pages or the home page, or any of the analytics data we capture around video views, etc. And our editorial team want to see in real time how their articles are performing so they can tweak them, move them around on the home page, etc.</p>
<p>To enable real-time slice and dice capabilities we hold LOTS of counters in Redis. The general schema for these is:</p>
<pre>dimension1:dimension2:dimension3:dimension4:articleId:dimension5:date:hour:minute = counter</pre>
<p>What the individual dimensions are is largely irrelevant for this post. Many (but not all) of the fields can also hold &#8220;*&#8221; instead of real data. And there can be many permutations of fields with real data in and fields with &#8220;*&#8221; in. So, for example, we might have the following:</p>
<pre>d1:d2:d3:d4:articleId:d5:date:hour:* = counter</pre>
<p> to represent all the views to a particular article across the 5 other dimensions in a given hour. Or </p>
<pre>d1:d2:d3:d4:*:d5:date:*:* = counter</pre>
<p> to represent all the views across dimensions d1-d5 for any article on a given date.</p>
<p>So each of the 500 hits per second that the analytics platform receives can generate a large number of Redis updates to satisfy the various combinations of wildcards. Our two primary Redis instances rumble along at a sustained rate of around 20,000 operations per second.</p>
<p>Now, all of this data takes space. Serious space. We shard this data across a number of Redis instance based on what type of data it is (page views, visitor data, video data, metadata, etc.). Following the release of some new business requirements recently, our two primary instances were using in the region of 20-24 GB of RAM each, and holding something like 110,000,000 keys each. Ouch!</p>
<p>A bit of lateral thinking was required.</p>
<p>Those keys work out on average around 40 bytes each. And the counters in them are, on average, around 2-3 bytes. That&#8217;s a massive overhead for the key names. The key names represent around 90% of the memory usage and the actual data only around 10%. And the keys contain an awful lot of duplication too &#8211; for example, dimension 1 can only take 2 possible values, but they are represented by a 4 character string and a 5 character string. So we store that 4 or 5 character string in EVERY SINGLE KEY.</p>
<p>There are a number of possible approaches to this including simply shortening the segments by making them a bit less semantically meaningful (for example, instead of storing dates as `20130815` we could store something like the number of days since January 1st 2010), or using some kind of dictionary-based approach whereby we assign every unique value that a dimension could have to an integer and then have keys that look like 12:3917:2385:1222:98737:3746:5543. Good luck debugging either of those.</p>
<p>In the end we took a pretty simple approach. We realised that the article ID dimension had by far the largest cardinality. So instead of making it part of the key and having Redis keep simple counters, we instead changed the Redis data structures to hashes keyed on the article ID. Thus:</p>
<pre>d1:d2:d3:d4:articleId:d5:date:hour:minute = counter</pre>
<p> becomes</p>
<pre>d1:d2:d3:d4:d5:date:hour:minute = hash of articleID -> counter</pre>
<p>By this simple expedient, we managed to reduce the memory usage on the primary servers from around 24GB to around 8GB (a saving of 66%) and the number of keys from 110,000,000 to around 2,500,000 (a saving of around 98%!). Ops team love us. CTO&#8217;s budget spreadsheet is looking more chilled out. Epic win.</p>
<p>There are a number of other advantages to this approach beyond the obvious reduction in hardware:</p>
<p>1) Because we&#8217;re using so much less memory, dumping RDB files is much quicker.<br />
2) Because writing RDB files is much quicker, the number of changes that happen during the dump is greatly reduced meaning less memory pressuring during the dump.<br />
3) The new data structure exhibits much better locality of reference, meaning that for any given workload that happens during the dump, fewer pages need to be copied. This means, again, even less memory pressure during RDB dump.</p>
<p>It does have some drawbacks though. In particular, you have changed the data access paths.</p>
<p>One of our screens has a &#8220;sparkline&#8221; of how a particular article has trended over the last 2 hours. Previously, we would gather the data for this by issuing a single Redis MGET command with 120 keys (one for each minute) where the hour and minute fields in the key ranged over the time period we were interested in.</p>
<p>Now, however, we cannot do that because there is no command in Redis to get one hash member (the article ID) out of 120 different hashes. The solution to this is a story for a different post&#8230;</p>
<p>So the moral of this story is this. When you are working with large volumes of data in a data store (but an in-memory one in particular):</p>
<p>1) Never let a prototype go live <img src="https://s.w.org/images/core/emoji/2.3/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />
2) Think about whether your primary workload will be storage or retrieval.<br />
3) Optimise your schema (in this case, the Redis key structure) accordingly.<br />
4) Understand your data and think about how you&#8217;re storing it.</p>
<p>(This is also a good opportunity to mention that we took the data in the old storage format and migrated it to the new format using my Node.JS-based <a href="https://github.com/codeaholics/node-rdb-tools" title="streaming RDB toolkit" target="_blank">streaming RDB toolkit</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2013/redis-memory-optimisation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Emulating Maven&#8217;s &#8220;provided&#8221; scope in Gradle</title>
		<link>http://blog.codeaholics.org/2012/emulating-mavens-provided-scope-in-gradle/</link>
		<comments>http://blog.codeaholics.org/2012/emulating-mavens-provided-scope-in-gradle/#comments</comments>
		<pubDate>Tue, 02 Oct 2012 20:27:28 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Build]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=252</guid>
		<description><![CDATA[I&#8217;m not a fan of Maven. I don&#8217;t make any secret of it. But one thing they&#8217;ve got right is the &#8220;provided&#8221; scope &#8211; that is, a scope whose dependencies are used at compile time, but not required at runtime &#8230; <a href="http://blog.codeaholics.org/2012/emulating-mavens-provided-scope-in-gradle/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m not a fan of Maven. I don&#8217;t make any secret of it. But one thing they&#8217;ve got right is the &#8220;provided&#8221; scope &#8211; that is, a scope whose dependencies are used at compile time, but not required at runtime because they&#8217;re expected to already be present. The canonical example of the use of this scope is the Servlet or JSP API &#8211; it needs to be present at compile time to compile against, but the container provides it at runtime, so it doesn&#8217;t need to be explicitly pulled in as a runtime dependency.</p>
<p>I <em>am</em> however, a big fan of Gradle. Gradle&#8217;s Java plugin provides a number of default &#8220;configurations&#8221; (revealing Gradle&#8217;s close relationship to Ivy) which bear a close resemblance to Maven&#8217;s scopes. However, the Java plugin doesn&#8217;t provide anything like Maven&#8217;s &#8220;provided&#8221; scope. (Note: the War plugin <em>does</em> provide both &#8220;providedCompile&#8221; and &#8220;providedRuntime&#8221; configurations.)</p>
<p>Why would you want a &#8220;provided&#8221; configuration in a Java project? Well, my particular use case was that I was writing a custom Ant task (I&#8217;m aware of the irony of using Gradle to build this!) and I needed to compile against the Ant API &#8211; but, of course, at run time the Ant JAR is already present.</p>
<p>Having pieced together a number of posts on the internet, I came up with the following:</p>
<pre class="brush: groovy; title: ; notranslate">
configurations {
    provided
}

sourceSets {
    main.compileClasspath += configurations.provided
    test.compileClasspath += configurations.provided
    test.runtimeClasspath += configurations.provided
}

dependencies {
    provided 'org.apache.ant:ant:1.8.4'
}
</pre>
<p>This works, but it feels a bit dirty.</p>
<p>If you&#8217;re an Eclipse user (of course you are!) it also has one major flaw. If you&#8217;re using the Eclipse STS Gradle plugin to create a managed classpath in your Eclipse project (rather than using Gradle&#8217;s Eclipse plugin to generate your <code>.classpath</code> and <code>.project</code> files), you&#8217;ll find that Eclipse doesn&#8217;t know anything about your &#8220;provided&#8221; dependencies and you have a bunch of compile errors.</p>
<p>Here&#8217;s how to sort that out:</p>
<pre class="brush: groovy; title: ; notranslate">
apply plugin: 'eclipse'

eclipse.classpath.plusConfigurations += configurations.provided
</pre>
<p>So, you have to add Gradle&#8217;s Eclipse plugin &#8211; even if you wouldn&#8217;t otherwise be using it &#8211; and add your &#8220;provided&#8221; dependencies to the Eclipse classpath configuration. Even if you don&#8217;t use the Gradle Eclipse plugin, the Eclipse STS Gradle plugin uses the same model and will now pick up your &#8220;provided&#8221; dependencies.</p>
<p>There is an outstanding Gradle bug report/enhancement request for this feature, but for some reason it&#8217;s struggling to get traction. If you feel this is important enough to be a built-in part of the Gradle Java plugin, please vote for <a href="http://issues.gradle.org/browse/GRADLE-784" target="_blank">this issue</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2012/emulating-mavens-provided-scope-in-gradle/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>World&#8217;s fastest break-in attempt</title>
		<link>http://blog.codeaholics.org/2012/worlds-fastest-break-in-attempt/</link>
		<comments>http://blog.codeaholics.org/2012/worlds-fastest-break-in-attempt/#respond</comments>
		<pubDate>Mon, 16 Apr 2012 19:14:16 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=244</guid>
		<description><![CDATA[Actually, I&#8217;m pretty sure it isn&#8217;t, but still&#8230; From spinning up a new EC2 instance today to getting the first e-mail from fail2ban took a little under 6 hours. I don&#8217;t know if this makes me happy or sad. Happy &#8230; <a href="http://blog.codeaholics.org/2012/worlds-fastest-break-in-attempt/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Actually, I&#8217;m pretty sure it isn&#8217;t, but still&#8230;</p>
<p>From spinning up a new EC2 instance today to getting the first e-mail from <a href="http://www.fail2ban.org" title="fail2ban" target="_blank">fail2ban</a> took a little under 6 hours.</p>
<p>I don&#8217;t know if this makes me happy or sad. Happy because I have a <a href="http://puppetlabs.com/" title="Puppet Labs" target="_blank">Puppet-based</a> bootstrap system which can bring a freshly minted box up to code in around 5 minutes (including <code>iptables</code>, <code>fail2ban</code> and a locked down SSH configuration), or sad because&#8230; well&#8230; have people really got nothing better to do?</p>
<p>In related news, when <em>will</em> <code>fail2ban</code> support IPv6? There seem to be lots of threads in lots of different issue tracking systems (most lately <a href="https://github.com/fail2ban/fail2ban/issues" title="Github" target="_blank">Github</a>), many of which include patches, but no actual IPv6 action. Now <em>that</em> makes me sad. <img src="https://s.w.org/images/core/emoji/2.3/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2012/worlds-fastest-break-in-attempt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress, nginx, W3TC and robots.txt</title>
		<link>http://blog.codeaholics.org/2012/wordpress-nginx-w3tc-and-robots-txt/</link>
		<comments>http://blog.codeaholics.org/2012/wordpress-nginx-w3tc-and-robots-txt/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 15:29:58 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=234</guid>
		<description><![CDATA[A quick note to try and save somebody else the hours of pain I just experienced&#8230; Here&#8217;s the scenario: you&#8217;re being dead clever and ditching Apache in favour of Nginx to run your WordPress blog/site and pretty much have everything &#8230; <a href="http://blog.codeaholics.org/2012/wordpress-nginx-w3tc-and-robots-txt/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A quick note to try and save somebody else the hours of pain I just experienced&#8230;</p>
<p>Here&#8217;s the scenario: you&#8217;re being dead clever and ditching Apache in favour of Nginx to run your WordPress blog/site and pretty much have everything right. You&#8217;re NOT using a plugin to generate <code>robots.txt</code> for you &#8211; after all, WordPress does a good enough job through the <code>Settings > Privacy page</code>. You browse to <code>http://domain.com/robots.txt</code> and everything looks pretty sweet. Heck, you might even go and change the privacy settings and grab <code>robots.txt</code> again to make sure it&#8217;s all working the way you expect.</p>
<p>Then&#8230; you drop the <a href="http://wordpress.org/extend/plugins/w3-total-cache/" title="W3 Total Cache" target="_blank">W3 Total Cache</a> bomb. Now, W3TC is pretty well regarded, but it hasn&#8217;t had any love for a several months. In fact, it hasn&#8217;t even been updated to say it&#8217;s compatible with WordPress 3.3.0+ (which it appears to be, AFAICT, although some people have had issues with Minify). What it <em>does</em> have though, is Nginx support out of the box.</p>
<p>What does that mean? Well, if W3TC detects that it is running on Nginx, it will write out a snippet of Nginx configuration which deals with all the cleverness needed to get Nginx to serve W3TC page cache files statically off the disk without having to go through PHP. (This, my friends, is a large part of the secret sauce that makes an Nginx/PHP stack so much faster than Apache/PHP.) Theoretically, all you have to do is use the <code>include</code> directive to pull this snippet into your virtual host configuration file, and you&#8217;re good to go. (If you do this then don&#8217;t forget to <code>nginx -s reload</code> every time you tweak your W3TC settings.)</p>
<p>And then it hits you. <code>robots.txt</code> has stopped working.</p>
<p>Here&#8217;s my solution (in my virtual host file, if you care):</p>
<pre class="brush: plain; title: ; notranslate">
    location = /robots.txt {
        # Force robots.txt through the PHP. This supercedes a match in the
        # generated W3TC rules which forced a static file lookup
        rewrite ^ /index.php;
    }
</pre>
<p>This is a pretty specific location (using <code>=</code> and not having a regexp), so it trumps anything in the W3TC generated config. Any request for <code>robots.txt</code> is rewritten to <code>index.php</code> which your regular Nginx rules should then hand off to PHP-FPM, which means WordPress will dynamically generate the content for you.</p>
<p>Wow. That took me, literally, 2-3 hours to figure out. Mostly because I didn&#8217;t notice it had stopped working when I added W3TC into the mix. Once I&#8217;d figured out W3TC (or rather the W3TC generated config) was the culprit, the actual fix was pretty quick.</p>
<p>I&#8217;ll be writing more about my Nginx config and the relative performance against Apache2 on an Amazon EC2 Micro instance soon. In the mean time, I hope I saved you some time!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2012/wordpress-nginx-w3tc-and-robots-txt/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Adventures with DD-WRT and IPv6 (with a dash of TomatoUSB)</title>
		<link>http://blog.codeaholics.org/2012/adventures-with-dd-wrt-and-ipv6-with-a-dash-of-tomatousb/</link>
		<comments>http://blog.codeaholics.org/2012/adventures-with-dd-wrt-and-ipv6-with-a-dash-of-tomatousb/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 21:59:59 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=199</guid>
		<description><![CDATA[A little under a year ago, I decided two things: first, that it was about time my ageing home network got GigE and 5GHz wireless-N (dual band, of course, to support devices that would only do 2.4GHz); and second, that &#8230; <a href="http://blog.codeaholics.org/2012/adventures-with-dd-wrt-and-ipv6-with-a-dash-of-tomatousb/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A little under a year ago, I decided two things: first, that it was about time my ageing home network got GigE and 5GHz wireless-N (dual band, of course, to support devices that would only do 2.4GHz); and second, that I would separate the jobs of BEING my network from CONNECTING my network to the internet (since I couldn&#8217;t find a good router which would meet these requirements AND had an ADSL modem in it).</p>
<p>So I bought a Linksys/Cisco E3000, made it the backbone of my network and connected it to the internet via my ISP-supplied ADSL modem.</p>
<p>Then an unfortunate incident happened which involved the Linksys/Cisco setup CD, an unwanted but non-removable guest WiFi network, and me swearing a lot.</p>
<p>The time had come (after about 16 hours!) to put <a href="http://www.dd-wrt.com/">DD-WRT</a> on my router. As <a href="http://www.dslreports.com/forum/remark,26665609" target="_blank">this post</a> describes, choosing a version of DD-WRT that won&#8217;t &#8220;brick&#8221; your router (as the developers like to describe it) is treacherous to say the least. I eventually settled on <code>dd-wrt.v24-16758_NEWD-2_K2.6_mega</code> (specifically, the <code>nv60k</code> version). Despite the trepidation caused by the dire warnings on the web site, the flashing went well, and I&#8217;ve been pleased with DD-WRT ever since. Until&#8230;</p>
<p>Last week, I had a 40Mbit/sec fibre broadband connection installed. Amongst other things, <a href="http://aaisp.net.uk/">my new ISP</a> provides me with a block of IPv6 addresses. Actually 2^80 of them. I seriously need to think about what I&#8217;m going to do with them all.</p>
<p>My excitement at having 1,208,925,819,614,629,174,706,176 IP addresses was somewhat dampened when, after a day or so of fiddling and researching, I discovered that DD-WRT&#8217;s supposed IPv6 support was limited to the various types of v6-over-v4 tunnels (e.g. <a href="http://tunnelbroker.net/">Hurricane Electric</a>). Specifically, the PPP daemon doesn&#8217;t support IPv6 &#8211; so this might just be an issue for PPPoE users. There was no way for me to use all that space natively.</p>
<p>It should be noted here that even if you do want to use a tunnel to reach the IPv6 internet, you will still need to write startup scripts for DD-WRT to load the kernel module (the &#8220;Enable IPv6&#8221; checkbox doesn&#8217;t actually do anything), start <code>radvd</code> (the &#8220;Enable radvd&#8221; checkbox doesn&#8217;t actually do anything), configure the tunnel interfaces and WAN IP addresses, etc. And even after all of this, you&#8217;ll find that the IPv6 user tools (ip6tables, ping6, traceroute6, etc.) aren&#8217;t installed, so you&#8217;ll have to locate them and hope you have room on your device somewhere.</p>
<p>So the time has come to make the move to <a href="http://tomatousb.org/">TomatoUSB</a>. To some extent, this suffers from the same issues as DD-WRT when it comes to variants, etc., but the information is more logically presented, and there do seem to be fewer choices and fewer potential traps. After looking at the comparison of &#8220;mods&#8221; on <a href="http://en.wikipedia.org/wiki/Tomato_(firmware)">Wikipedia</a>, I chose Toastman&#8217;s mod. It seems to have all the features I wanted and he seems to do frequent builds with all the latest updates and patches &#8211; in fact, the latest build (1.28.7494.3) was made only 6 days ago. This compares well with DD-WRT which doesn&#8217;t appear to have had any real active work/releases for a year or so now.</p>
<p>My first impressions of TomatoUSB are positive. The GUI feels snappy, and has most of the same features as DD-WRT. The real-time bandwidth monitor is definitely prettier than DD-WRTs. And, most importantly, the IPv6 support works out of the box.</p>
<p><a href="http://blog.codeaholics.org/2012/adventures-with-dd-wrt-and-ipv6-with-a-dash-of-tomatousb/tomato-ipv6-3/" rel="attachment wp-att-215"><img src="http://blog.codeaholics.org/wp-content/uploads/2012/01/tomato-ipv62.png?x96567" alt="TomatoUSB IPv6 configuration screen" title="tomato-ipv6" width="901" height="870" class="aligncenter size-full wp-image-215" srcset="http://blog.codeaholics.org/wp-content/uploads/2012/01/tomato-ipv62.png 901w, http://blog.codeaholics.org/wp-content/uploads/2012/01/tomato-ipv62-300x289.png 300w" sizes="(max-width: 901px) 100vw, 901px" /></a></p>
<p>Out-of-the-box, <code>ip6tables</code> is configured to allow ICMP packets of every type (so I can ping all my machines from various online ping sites), but disallow all inbound traffic. So, Linux ip6tables bugs aside, I&#8217;m secure by default, which is nice. There doesn&#8217;t seem to be a GUI interface to setup firewall rules for IPv6, so I guess if I ever to want to let anything in, I&#8217;ll have to ssh to the router and do it by hand &#8211; but why would I ever want that?</p>
<p>And that&#8217;s that. I took under 2 hours to flash TomatoUSB, reproduce all my configuration on it, and get IPv6 working. Nice. I can now browse <a href="http://ipv6.google.com/">ipv6.google.com</a>, <a href="http://www.v6.facebook.com">www.v6.facebook.com/</a>, and I get a dancing turtle when I visit <a href="http://www.kame.net/">www.kame.net</a>. Also, this:</p>
<p><a href="http://blog.codeaholics.org/2012/adventures-with-dd-wrt-and-ipv6-with-a-dash-of-tomatousb/test-ipv6-screenshot/" rel="attachment wp-att-212"><img src="http://blog.codeaholics.org/wp-content/uploads/2012/01/test-ipv6-screenshot-1024x980.png?x96567" alt="Results from test-ipv6.com" title="test-ipv6-screenshot" width="1024" height="980" class="aligncenter size-large wp-image-212" srcset="http://blog.codeaholics.org/wp-content/uploads/2012/01/test-ipv6-screenshot-1024x980.png 1024w, http://blog.codeaholics.org/wp-content/uploads/2012/01/test-ipv6-screenshot-300x287.png 300w, http://blog.codeaholics.org/wp-content/uploads/2012/01/test-ipv6-screenshot.png 1025w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p><b>One last thing:</b> don&#8217;t forget to enable IPv6 privacy extensions on all of your hosts!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2012/adventures-with-dd-wrt-and-ipv6-with-a-dash-of-tomatousb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iTunes 10.5 upgrade woes</title>
		<link>http://blog.codeaholics.org/2011/itunes-10-5-upgrade-woes/</link>
		<comments>http://blog.codeaholics.org/2011/itunes-10-5-upgrade-woes/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 21:26:02 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=195</guid>
		<description><![CDATA[iOS 5 is upon us, so I thought I would snag a copy and see what&#8217;s what. But, first thing&#8217;s first&#8230; I apparently needed to upgrade iTunes to 10.5. (Why? Why do I need a particular version of a media &#8230; <a href="http://blog.codeaholics.org/2011/itunes-10-5-upgrade-woes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>iOS 5 is upon us, so I thought I would snag a copy and see what&#8217;s what. But, first thing&#8217;s first&#8230; I apparently needed to upgrade iTunes to 10.5. (Why? Why do I need a particular version of a media player to install a particular version of a mobile phone OS?)</p>
<p>I&#8217;m running Windows Vista (yes, really) Ultimate x64 SP2 with all current patches applied. After the obligatory unchecking of unwanted crap from the Apple software update tool (specifically, MobileMe and Safari), I settled in to watch the very slow download. I guess Apple&#8217;s servers are a bit overloaded right now. And then the very slow installation process begins. And then&#8230; the very slow installation process aborts.</p>
<p>Hmmm. Try again. At least it didn&#8217;t seem to need to do the download again. Same failure. No real error message. Just &#8220;failed to install&#8221; or something equally unhelpful.</p>
<p>A quick Google turned up lots of people having this problem. Some on Windows 7, some on Vista. All on x64. The typical advice was to try installing as an administrator, try downloading and running the MSI by hand, try both (manual install as an administrator). None of it helped. It did, however, reveal a more useful error message. “Service ‘iPod Service’ (iPod Service) could not be installed. Verify that you have sufficient privileges to install system services.”</p>
<p>Googling this turned up <a href="http://planetmediocrity.com/2010/09/itunes-10-installation-problem-and-solution/">a year-old blog post by David Lesault</a> which hit the spot.</p>
<p>Essentially, it seems the installer has issues uninstalling the iPod Service sometimes (I&#8217;ve never had this problem before, others seem to have had it since the genesis of iTunes 10.x). The service is marked for deletion, but not quite gone yet. Hence trying to install the new version of the service failed. This is similar to that funky Windows things where it can&#8217;t delete files that are in use by a process, but remembers them and deletes them when you reboot. Which, incidentally, is one of the primary reasons why Windows insists on reboots after various kinds of patches, although this is much, much better in Vista and later.</p>
<p>So, I slightly altered David&#8217;s process. I got myself to the error message and then simply switched my machine off (hold the power button for 4 seconds). When I restarted and tried the install again, MSI said that a pending installation was in progress and I would need to roll that back before continuing, which I duly did. I was a bit worried that the &#8220;rollback&#8221; would reinstall the old version of the service, but it didn&#8217;t seem to. And that&#8217;s that&#8230; the iTunes 10.5 upgrade successfully installed.</p>
<p>Now, only 7 minutes left of the iOS 5 download, and who knows how long it will take to actually upgrade the phone and what issues I will have&#8230;?</p>
<p>Thanks Apple. :-/</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2011/itunes-10-5-upgrade-woes/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Disruptor.NET</title>
		<link>http://blog.codeaholics.org/2011/disruptor-net/</link>
		<comments>http://blog.codeaholics.org/2011/disruptor-net/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 19:53:13 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=177</guid>
		<description><![CDATA[It&#8217;s interesting to see people getting interested in porting the Disruptor to .NET (although what&#8217;s wrong with The One True Language, I don&#8217;t know!). Tim Gebhardt has a port on Github Matt Davey (Technical Director at Lab49) also has a &#8230; <a href="http://blog.codeaholics.org/2011/disruptor-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>It&#8217;s interesting to see people getting interested in porting the Disruptor to .NET (although what&#8217;s wrong with The One True Language, I don&#8217;t know!).</p>
<ul>
<li>Tim Gebhardt has <a href="https://github.com/TimGebhardt/Disruptor.NET">a port</a> on Github</li>
<li>Matt Davey (Technical Director at Lab49) also has a couple of posts about <a href="http://mdavey.wordpress.com/2011/06/30/disruptor-net-concurrent-programming-framework-for-net-framework/">porting the Disruptor</a> and <a href="http://mdavey.wordpress.com/2011/06/30/initlal-java-vs-net-disruptor-performance-comparison/">comparing the performance</a> of his port to the Java version</li>
</ul>
<p>I&#8217;ll try to keep this post updated as I learn of more .NET interest. Alternatively, please feel free to post a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2011/disruptor-net/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Disruptor &#8211; Lock-free publishing</title>
		<link>http://blog.codeaholics.org/2011/the-disruptor-lock-free-publishing/</link>
		<comments>http://blog.codeaholics.org/2011/the-disruptor-lock-free-publishing/#comments</comments>
		<pubDate>Tue, 28 Jun 2011 16:57:11 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=156</guid>
		<description><![CDATA[In case you&#8217;ve been living on another planet, we recently our high performance message passing framework. I&#8217;m going to give a quick run-down on how we put messages into the ring buffer (the core data structure within the Disruptor) without &#8230; <a href="http://blog.codeaholics.org/2011/the-disruptor-lock-free-publishing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In case you&#8217;ve been living on another planet, we recently <a href="http://blog.codeaholics.org/2011/open-sourcing-the-disruptor/">open-sourced</a> <a href="http://mikes-tech.blogspot.com/2011/06/disruptor-now-open-source.html" target="_blank">our</a> <a href="http://mechanitis.blogspot.com/2011/06/dissecting-disruptor-whats-so-special.html" target="_blank">high</a> <a href="http://www.davefarley.net/?p=151" target="_blank">performance</a> <a href="http://code.google.com/p/disruptor/" target="_blank">message passing framework</a>.</p>
<p>I&#8217;m going to give a quick run-down on how we put messages into the ring buffer (the core data structure within the Disruptor) without using any locks.<br />
<span id="more-156"></span><br />
Before going any further, it&#8217;s worth a quick read of <a href="http://mechanitis.blogspot.com/2011/06/dissecting-disruptor-whats-so-special.html" target="_blank">Trish&#8217;s post</a>, which gives a high-level overview of the ring buffer and how it works.</p>
<p>The salient points from this post are:</p>
<ol>
<li>The ring buffer is nothing but a big array.</li>
<li>All &#8220;pointers&#8221; into the ring buffer (otherwise known as sequences or cursors) are Java longs (64 bit signed numbers) and count upward forever. (Don&#8217;t panic &#8211; even at 1,000,000 messages per second, it would take the best part of 300,000 years to wrap around the sequence numbers).</li>
<li>These pointers are then &#8220;mod&#8217;ed&#8221; by the ring buffer size to figure out which array index holds the given entry. For performance, we actually force the ring buffer size to be the next power of two bigger than the size you ask for, and then we can use a simple bit-mask to figure out the array index.</li>
</ol>
<h3>Basic ring buffer structure</h3>
<p>WARNING: In terms of the organisation of the <a href="http://code.google.com/p/disruptor/" target="_blank">code</a>, much of what I&#8217;m about to say is a simplification. Conceptually, I think it&#8217;s simpler to understand starting from how I describe it.</p>
<p>The ring buffer maintains two pointers, &#8220;next&#8221; and &#8220;cursor&#8221;:</p>
<p><a href="http://blog.codeaholics.org/wp-content/uploads/2011/06/basic-structure.jpg?x96567"><img src="http://blog.codeaholics.org/wp-content/uploads/2011/06/basic-structure-300x135.jpg?x96567" alt="" title="Basic Structure" width="300" height="135" class="aligncenter size-medium wp-image-158" srcset="http://blog.codeaholics.org/wp-content/uploads/2011/06/basic-structure-300x135.jpg 300w, http://blog.codeaholics.org/wp-content/uploads/2011/06/basic-structure-1024x462.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>In the picture above, a ring buffer of size 7 (hey, you know how these hand-drawn diagrams work out sometimes!) has slots 0 through 2 filled with data. The next pointer refers to the first free slot. The cursor refers to the last filled slot. In an idle ring buffer, they will be adjacent to each other as shown.</p>
<h3>Claiming a slot</h3>
<p>The Disruptor API has a transactional feel about it. You &#8220;claim&#8221; a slot in the ring buffer, then you write your data into the claimed slot, then you &#8220;commit&#8221; the data.</p>
<p>Let&#8217;s assume there&#8217;s a thread that wants to put the letter &#8220;D&#8221; into the ring buffer. It claims a slot. The claim operation is nothing more than a <a href="http://en.wikipedia.org/wiki/Compare-and-swap" target="_blank">CAS</a> &#8220;get-and-increment&#8221; operation on the next pointer. That is, this thread (let&#8217;s call it thread D) simply does an atomic get-and-increment which moves the next pointer to 4, and returns 3. Thread D has now claimed slot 3:<br />
<a href="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-claim.jpg?x96567"><img src="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-claim-300x197.jpg?x96567" alt="" title="After thread D claims a slot" width="300" height="197" class="aligncenter size-medium wp-image-160" srcset="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-claim-300x197.jpg 300w, http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-claim-1024x674.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Next, another thread (thread E) claims slot 4 in the same manner:</p>
<p><a href="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-claim.jpg?x96567"><img src="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-claim-300x233.jpg?x96567" alt="" title="After thread E claims a slot" width="300" height="233" class="aligncenter size-medium wp-image-163" srcset="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-claim-300x233.jpg 300w, http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-claim-1024x797.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h3>Committing the writes</h3>
<p>Now, threads D and E can both safely and simultaneously write their data into their respective slots. But let&#8217;s say that thread E finishes first for some reason&#8230;</p>
<p>Thread E attempts to commit its write. The commit operation consists of a CAS operation in a busy-loop. Since thread E claimed slot 4, it does a CAS waiting for the cursor to get to 3 and then setting it to 4. Again, this is an atomic operation. So, as the ring buffer stands right now, thread E is going to spin because the cursor is set to 2 and it (thread E) is waiting for the cursor to be at 3.</p>
<p>Now thread D commits. It does a CAS operation and sets the cursor to 3 (the slot it claimed) <a href="http://en.wikipedia.org/wiki/If_and_only_if" target="_blank">iff</a> the cursor is currently at 2. The cursor <i>is</i> currently at 2, so the CAS succeeds and the commit succeeds. At this point, cursor has been updated to 3 and all data up to that sequence number is available for reading.</p>
<p>This is an important point. Knowing how &#8220;full&#8221; the ring buffer is &#8211; i.e. how much data has been written, which sequence number represents the highest write, etc. &#8211; is purely a function of the cursor. The next pointer is only used for the transactional write protocol.</p>
<p><a href="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-commits.jpg?x96567"><img src="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-commits-300x233.jpg?x96567" alt="" title="After D commits" width="300" height="233" class="aligncenter size-medium wp-image-167" srcset="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-commits-300x233.jpg 300w, http://blog.codeaholics.org/wp-content/uploads/2011/06/after-d-commits-1024x797.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The final step in the puzzle is making thread E&#8217;s write visible. Thread E is still spinning trying to do an atomic update of the cursor from 3 to 4. Now the cursor is at 3, its next attempt will succeed:</p>
<p><a href="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-commits.jpg?x96567"><img src="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-commits-300x233.jpg?x96567" alt="" title="After thread E commits" width="300" height="233" class="aligncenter size-medium wp-image-169" srcset="http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-commits-300x233.jpg 300w, http://blog.codeaholics.org/wp-content/uploads/2011/06/after-e-commits-1024x797.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h3>Summary</h3>
<p>The order that writes are visible is defined by the order in which threads claim slots rather than the order they commit their writes, but if you imagine these threads are pulling messages of a network messaging layer then this is really no different from the messages arriving at slightly different times, or the two threads racing to the slot claim in a different order.</p>
<p>So there we have it. It&#8217;s a pretty simple and elegant algorithm. (OK, I admit I was heavily involved in its creation!) Writes are atomic, transactional and lock-free, even with multiple writing threads.</p>
<p>(Thanks to Trish for the inspiration for the hand-drawn diagrams!)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2011/the-disruptor-lock-free-publishing/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Open sourcing the Disruptor</title>
		<link>http://blog.codeaholics.org/2011/open-sourcing-the-disruptor/</link>
		<comments>http://blog.codeaholics.org/2011/open-sourcing-the-disruptor/#comments</comments>
		<pubDate>Tue, 21 Jun 2011 09:14:37 +0000</pubDate>
		<dc:creator><![CDATA[Danny]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.codeaholics.org/?p=130</guid>
		<description><![CDATA[LMAX recently&#160;open-sourced The Disruptor &#8211; one of the core frameworks upon which we build our ultra-high performance financial exchange. Today, we published a white paper detailing how The Disruptor works, and highlighting the sorts of performance benefits that can be &#8230; <a href="http://blog.codeaholics.org/2011/open-sourcing-the-disruptor/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.lmax.com" target="_blank">LMAX</a> recently&nbsp;open-sourced <a href="http://code.google.com/p/disruptor/" target="_blank">The Disruptor</a> &#8211; one of the core frameworks upon which we build our ultra-high performance financial exchange. Today, we published a <a href="http://disruptor.googlecode.com/files/Disruptor-1.0.pdf" target="_blank">white paper</a> detailing how The Disruptor works, and highlighting the sorts of performance benefits that can be achieved by using it.</p>
<p>The Disruptor is essentially a library which we (and now you!) can use to do message passing within your application. If you like, it&#8217;s a queue on steroids. But this stuff is far more fascinating than just that for a number of reasons.<br />
<span id="more-130"></span></p>
<p>Firstly, the raw performance figures. Our testing shows that the latency you can achieve with The Disruptor is 3 orders of magnitude less than you can achieve with <tt>ArrayBlockingQueue</tt>. And with that, comes throughput that&#8217;s an order of magnitude higher! Win-win. But there&#8217;s more. The Disruptor actually goes <i>faster</i> under higher load. We&#8217;ve had this monster passing messages with latencies as low as <i>50ns</i>. That&#8217;s approaching the theoretical limit of what you can achieve with the hardware. Still think Java is slow?</p>
<p>Here&#8217;s a chart from the white paper, showing the relative latencies. It&#8217;s worth keeping in mind that this chart uses a log-log scale.<br />
<img src="http://blog.codeaholics.org/wp-content/uploads/2011/06/latency-histogram.png?x96567" alt="Latency Histogram" title="latency-histogram" width="629" height="371" class="aligncenter size-full wp-image-147" srcset="http://blog.codeaholics.org/wp-content/uploads/2011/06/latency-histogram.png 629w, http://blog.codeaholics.org/wp-content/uploads/2011/06/latency-histogram-300x176.png 300w" sizes="(max-width: 629px) 100vw, 629px" /><br />
Secondly, the implementation approach. The Disruptor has been designed and built by stepping away from the problem, and re-evaluating it from a CS101 perspective. A lot of the principles used fly in the face of modern, main-stream concurrency ideas. For example, most deployments of The Disruptor will allow you pass messages from multiple producers to multiple consumers without a single lock. Not locking means not going to the kernel for lock arbitration, and that means no latency spikes.</p>
<p>Thirdly, the&nbsp;consistency. In our tests, <tt>ArrayBlockingQueue</tt> was giving us a mean latency of over 30,000ns, and a 99.99% tail of 4,000,000ns. The Disruptor was showing a mean latency of just 52ns, and a 99.99% tail of around 8,000ns. The consistency with which The Disruptor out-performs traditional queueing/message-passing techniques leads to less jitter and latency spikes. This is vital in a financial environment. Latency spikes lead to unhappy market makers who have no confidence in the prices they&#8217;re making. That leads to wider spreads. And that, ultimately, leads to unhappy customers.</p>
<p>Finally, you really have to hear <a href="http://www.infoq.com/presentations/LMAX" target="_blank">Martin Thompson</a> (our CTO) and <a href="http://skillsmatter.com/podcast/java-jee/how-to-do-100k-tps-at-less-than-1ms-latency" target="_blank">Mike Barker</a> (one&nbsp;of our tech leads) talk about this stuff to understand the passion that they put into its creation.</p>
<p>EDIT: Turns out Mike Barker has written a <a href="http://mikes-tech.blogspot.com/2011/06/disruptor-now-open-source.html" target="_blank">similar post</a> today!</p>
<p>EDIT 2: Also, Trisha Gee has <a href="http://mechanitis.blogspot.com/2011/06/dissecting-disruptor-whats-so-special.html" target="_blank">written a post</a> which goes into some of the basics about what a ring buffer is. Can you tell we&#8217;re all quite excited?</p>
<p>For more information, checkout the <a href="http://code.google.com/p/disruptor/" target="_blank">Google code</a> project and the <a href="http://disruptor.googlecode.com/files/Disruptor-1.0.pdf" target="_blank">white paper</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeaholics.org/2011/open-sourcing-the-disruptor/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.w3-edge.com/products/

Object Caching 5/151 objects using disk
Page Caching using apc 
Database Caching using disk

Served from: blog.codeaholics.org @ 2021-02-11 16:43:44 by W3 Total Cache
-->