<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.igvita.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>igvita.com</title>
	
	<link>http://www.igvita.com</link>
	<description>A goal is a dream with a deadline.</description>
	<pubDate>Sat, 28 Aug 2010 19:12:31 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.igvita.com/igvita" /><feedburner:info uri="igvita" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>igvita</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Multi-core, Threads &amp; Message Passing</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/IkMxuajPRbM/</link>
		<comments>http://www.igvita.com/2010/08/18/multi-core-threads-message-passing/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 17:21:27 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[message-passing]]></category>

		<category><![CDATA[multi-core]]></category>

		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1268</guid>
		<description><![CDATA[Moore's Law marches on, the transistor counts are continuing to increase at the predicted rate and will continue to do so for the foreseeable future. However, what has changed is where these transistors are going: instead of a single core, they are appearing in multi-core designs, which place a much higher premium on hardware and [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" src="http://www.igvita.com/posts/10/multi-core.png" style="margin-right: 1em;margin-top:0.75em;"><a href="http://en.wikipedia.org/wiki/Moore's_law">Moore's Law</a> marches on, the transistor counts are continuing to increase at the predicted rate and will continue to do so for the foreseeable future. However, what has changed is <a href="http://en.wikipedia.org/wiki/Moore's_law#Transistor_count_versus_computing_performance">where</a> these transistors are going: instead of a single core, they are appearing in multi-core designs, which place a much higher premium on hardware and software parallelism. This is hardly news, I know. However, before we get back to arguing about the <strong>"correct"</strong> parallelism & concurrency abstractions (threads, events, actors, channels, and so on) for our software and runtimes, it is helpful to step back and take a closer look at the actual hardware and where it is heading.</p>
<h4><strong>Single Core Architecture & Optimizations</strong></h4>
<p><img align="left" src="http://www.igvita.com/posts/10/single-core.png" style="margin-right: 1em;"></p>
<p>The conceptual architecture of a single core system is deceivingly simple: single CPU, which is connected to a block of memory and a collection of other I/O devices. Turns out, simple is not practical. Even with modern architectures, the latency of a main memory reference (~100ns roundtrip) is prohibitively high, which combined with highly unpredictable control flow has led CPU manufacturers to introduce <a href="http://en.wikipedia.org/wiki/CPU_cache#Multi-level_caches">multi-level caches</a> directly onto the chip: Level 1 (L1) cache reference: ~0.5 ns; Level 2 (L2) cache reference: ~7ns, and so on.</p>
<p>However, even that is not enough. To keep the CPU busy, most manufacturers have also introduced some cache prefetching and management schemes (ex: Intel's <a href="http://www.intel.com/technology/product/demos/cache/demo.htm">SmartCache</a>), as well as invested billions of dollars into <a href="http://en.wikipedia.org/wiki/Branch_predictor">branch prediction</a>, <a href="http://en.wikipedia.org/wiki/Instruction_pipeline">instruction pipelining</a>, and other tricks to squeeze every ounce of performance. After all, if the CPU has a separate floating point and an integer unit, then there is no reason why two threads of execution could not simultaneously run on the same chip - see <a href="http://en.wikipedia.org/wiki/Simultaneous_multithreading">SMT</a>. Remember Intel's <a href="http://en.wikipedia.org/wiki/Hyper-threading">Hyperthreading</a>? As another point of reference, Sun's <a href="http://en.wikipedia.org/wiki/UltraSPARC_T1">Niagara chips</a> are designed to run <a href="http://www.eetimes.com/electronics-news/4059429/Panel-confronts-multicore-pros-and-cons">four execution threads</a> per core.</p>
<p>But wait, how did threads get in here? Turns out, threads are a way to expose the potential (and desired) hardware parallelism to the rest of the system. Put another way,<strong> threads are a low-level hardware and operating system feature</strong>, which we need to take full advantage of the underlying capabilities of our hardware.</p>
<h4><strong>Architecting for the Multi-core World</strong></h4>
<p>Since the manufacturers could no longer continue scaling the single core (power, density, communication), the designs have shifted to the next logical architecture: multiple cores on a single chip. After all, hardware parallelism existed all along, so the conceptual shift wasn't that large - shared memory, multiple cores, more concurrent threads of execution. Only one gotcha, remember those L1, L2 caches we introduced earlier? Turns out, they may well be the Achilles' heel for multi-core.</p>
<p align="left"><img src="http://www.igvita.com/posts/10/multi-core-architecture.png" /></p>
<p>If you were to design a multi-core chip, would you allow your cores to share the L1, or L2 cache, or should they all be independent? Unfortunately, there is one answer to this question. Shared caches can allow higher utilization, which may lead to power savings (ex: great for laptops), as well as higher hit rates in certain scenarios. However, that same shared cache can easily create resource contention if one is not careful (DMA is a <a href="http://en.wikipedia.org/wiki/Direct_memory_access#Cache_coherency_problem">known offender</a>). Intel's Core Duo and Xeon processors use a shared L2, whereas AMD's Opteron, Athlon, and Intel's Pentium D opted out for independent L1's and L2's. Even more interestingly, Intel's recent Itanium 2 gives each core an independent L1, L2, and an L3 cache! <strong>Different workloads benefit from different layouts</strong>.</p>
<p><img align="left" src="http://www.igvita.com/posts/10/coherence.png" style="margin-right: 1em;">As Phil Karlton once famously said:<em> "There are only two hard things in Computer Science: cache invalidation and naming things,"</em> and as someone cleverly added later, <em>"and off by one errors"</em>. Turns out, <a href="http://en.wikipedia.org/wiki/Cache_coherency">cache coherency</a> is a major problem for all multi-core systems: if we prefetch the same block of data into an L1, L2, or L3 of each core, and one of the cores happens to make a modification to its cache, then we have a problem - the data is now in an inconsistent state across the different cores. We can't afford to go back to main memory to verify if the data is valid on each reference (as that would defeat the purpose of the cache), and a shared mutex is the very anti-pattern of independent caches!</p>
<p>To address this problem, hardware designers have iterated over a number of data invalidation and propagation schemes, but the key point is simple: the cores share a bus or an interconnect over which messages are propagated to keep all of the caches in sync (<em>coherent</em>), and therein lies the problem. While, the numbers vary, the overall consensus is that after <a href="http://www.csa.com/discoveryguides/multicore/review3.php">approximately 32 cores</a> on a single chip, the amount of required communication to support the shared memory model leads to diminished performance. Put another way, <strong>shared memory systems have limited scalability</strong>.</p>
<h4><strong>Turtles all the way down: Distributed Memory</strong></h4>
<p><img align="left" src="http://www.igvita.com/posts/10/distributed-memory.png" style="margin-right: 1em;">So if cache coherence puts an upper bound on the number of cores we can support within the shared memory model, then lets drop the shared memory requirement! What if, instead of a monolithic view of the memory, each core instead had its own, albeit much smaller main memory? <a href="http://en.wikipedia.org/wiki/Distributed_memory">Distributed memory</a> model has the advantage of avoiding all of the cache coherency problems we listed above. However, it is also easy to imagine a number of workloads where the distributed memory will underperform the shared memory model.</p>
<p>There doesn't appear to be any consensus in the industry yet, but if one had to guess, then a hybrid model seems likely: <strong>push the shared memory model as far as you can, and then stamp it out multiple times on a chip, with a distributed memory interconnect</strong> - it is cache and interconnect turtles all the way down. In other words, while message passing may be a choice today, in the future, it may well be a requirement if we want to extract the full capabilities of the hardware.</p>
<h4><strong>Turtles all the way up: Web Architecture</strong></h4>
<p><img align="left" src="http://www.igvita.com/posts/10/web-cores.png" style="margin-right: 1em;">Most interesting of all, we can find the exact same architecture patterns and their associated problems in the web world. We start with a single machine running the app server and the database (CPU and main memory), which we later split into separate instances (multiple app servers share a remote DB, aka 'multi-core'), and eventually we shard the database (distributed memory) to achieve the required throughput. The similarity of the challenges and the approaches seems hardly like a coincidence. It is turtles all the way down, and it is turtles all the way up.</p>
<h4><strong>Threads, Events & Message Passing</strong></h4>
<p>As software developers, we are all intimately familiar with the shared memory model and the good news is: it is not going anywhere. However, as the core counts continue to increase, it is also very likely that we will quickly hit diminishing returns with the existing shared memory model. So, while we may disagree on whether threads are a correct application level API (see <a href="http://en.wikipedia.org/wiki/Process_calculus">process calculi variants</a>), they are also not going anywhere - either the VM, the language designer, or you yourself will have to deal with them.</p>
<p>With that in mind, the more interesting question to explore is not which abstraction is "correct" or "more performant" (one can always craft an optimized workload), but rather how do we make all of these paradigms work together, in a context of a simple programming model?<strong> We need threads, we need events, and we need message passing - it is not a question of which is better</strong>.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=IkMxuajPRbM:b9Rj94d3-rs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=IkMxuajPRbM:b9Rj94d3-rs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=IkMxuajPRbM:b9Rj94d3-rs:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=IkMxuajPRbM:b9Rj94d3-rs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=IkMxuajPRbM:b9Rj94d3-rs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=IkMxuajPRbM:b9Rj94d3-rs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=IkMxuajPRbM:b9Rj94d3-rs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=IkMxuajPRbM:b9Rj94d3-rs:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=IkMxuajPRbM:b9Rj94d3-rs:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/IkMxuajPRbM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/08/18/multi-core-threads-message-passing/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/08/18/multi-core-threads-message-passing/</feedburner:origLink></item>
		<item>
		<title>Rails 3 Internals: Railtie &amp; Creating Plugins</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/QgSn_7tAom0/</link>
		<comments>http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 16:58:19 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[plugin]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[railtie]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1249</guid>
		<description><![CDATA[With the official Rails 3 release on the horizon, all of the edge features we have been hearing about for over a year are about to become the new standard, and it has definitely been worth the wait. One of the primary goals of the "big refactor" has been to modularize Rails to allow other [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" src="http://www.igvita.com/posts/10/rails3.png" style="margin-right: 1em;">With the official Rails 3 release <a href="http://weblog.rubyonrails.org/2010/7/26/rails-3-0-release-candidate">on the horizon</a>, all of the edge features we have been hearing about for over a year are about to become the new standard, and it has definitely been worth the wait. One of the primary goals of the <em>"big refactor"</em> has been to modularize Rails to allow other frameworks to easily extend or entirely replace any of the previously <em>"critical"</em> components (ActiveRecord, ActionMailer, etc). At the centre of all this, is the new Railtie logic, which pieces all of these modules together.</p>
<h4><strong>Getting started with Railtie</strong></h4>
<p>The <a href="http://edgeapi.rubyonrails.org/classes/Rails/Railtie.html">documentation for Railtie</a> is a great place to get started, but the interesting observation is that each of the major Rails components (Action Mailer/Controller/View/Record) is itself a Railtie, and Rails as you know it is simply <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/app/templates/config/application.rb#L8">pieced together</a> by requiring all of the independent components. Even better, if your plugin or gem needs to hook into the Rails initialization process, all you need to do is inherit from Railtie and you are ready to go!</p>
<p>So how does Railtie know to call your classes and initializers? Railtie <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/railtie.rb#L138">defines</a> a <a href="http://ruby-doc.org/core/classes/Class.html#M002785">self.inherited</a> method, which is called anytime a subclass of Railtie is created, and stashes a reference to this class in a <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/railtie.rb#L135">@subclasses</a> variable. From there, the framework can simply call <a href="http://github.com/rails/rails/blob/master/railties/lib/rails/application/railties.rb#L16">Railtie.subclasses</a> and perform all the initialization as usual - a clever use of the Ruby object model.</p>
<h4><strong>Creating a Rails 3 plugin: 0-60</strong></h4>
<p>As a result of the refactor, creating Rails 3 plugins is at least several orders of magnitude simpler. In fact, as a simple exercise, lets create a custom notification plugin to print all of the internal Rails logging by also hooking into the new <a href="http://edgeapi.rubyonrails.org/classes/ActiveSupport/Notifications.html">Rails::Notification API</a>:</p>
<p><a href="javascript:showme('9676_1');"> <b>> railtie-plugin.rb</b></a>
<div style=" background:white;" id=9676_1>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">module</span> NewPlugin
  <span style="color:#008000; font-style:italic;"># namespace our plugin and inherit from Rails::Railtie</span>
  <span style="color:#008000; font-style:italic;"># to get our plugin into the initialization process</span>
  <span style="color:#9966CC; font-weight:bold;">class</span> Railtie &lt; <span style="color:#6666ff; font-weight:bold;">Rails::Railtie</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># configure our plugin on boot. other extension points such</span>
    <span style="color:#008000; font-style:italic;"># as configuration, rake tasks, etc, are also available</span>
    initializer <span style="color:#996600;">&quot;newplugin.initialize&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |app|
&nbsp;
      <span style="color:#008000; font-style:italic;"># subscribe to all rails notifications: controllers, AR, etc.</span>
      <span style="color:#6666ff; font-weight:bold;">ActiveSupport::Notifications</span>.<span style="color:#9900CC;">subscribe</span> <span style="color:#9966CC; font-weight:bold;">do</span> |*args|
        event = <span style="color:#6666ff; font-weight:bold;">ActiveSupport::Notifications::Event</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>*args<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Got notification: #{event.inspect}&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<p><a href="http://github.com/igrigorik/slowgrowl"><img align="left" src="http://www.igvita.com/posts/10/slowgrowl.png" style="margin-right: 1em; border:1px solid #aaa;"></a>Believe it or not, that is a fully functional Rails 3 plugin, in 10 lines of code. Simply drop this file into your load path and require it in your application. In fact, you can bundle this file into a gem, ship it to Gemcutter and with the help of <a href="http://github.com/carlhuda/bundler">Bundler</a>, all your users have to do is specify <strong>"<em>gem 'ournew-plugin'</em>"</strong> in their Gemfile, and the rest is taken care of. With a little more imagination, and fun, we can extend our example above into a '<a href="http://github.com/igrigorik/slowgrowl">slowgrowl</a>' plugin, which will - you guessed it - growl at the developer anytime it detects a slow code path in your app! Hat tip to <a href="http://hasmanyquestions.wordpress.com/2010/01/17/let-your-sql-growl-in-rails-3/">Gavin Stark</a> for the idea.</p>
<h4><strong>Getting started with Rails 3</strong></h4>
<p>Railtie while an important piece of Rails 3, is hardly the only component worth looking into. Also read up on the changes in <a href="http://m.onkey.org/2010/1/22/active-record-query-interface">ActiveRecord</a>, the <a href="http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/">new router</a>, watch the <a href="http://rubyonrails.org/screencasts/rails3">summary screencasts</a> on the Rails site, and make sure to check out one of the many great <a href="http://railscasts.com/tags/27">Railscasts</a> on the topic by Ryan Bates. It has been worth the wait, Rails 3 is easily head and shoulders above the competition.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=QgSn_7tAom0:-doig-qx-Dk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=QgSn_7tAom0:-doig-qx-Dk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=QgSn_7tAom0:-doig-qx-Dk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=QgSn_7tAom0:-doig-qx-Dk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=QgSn_7tAom0:-doig-qx-Dk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=QgSn_7tAom0:-doig-qx-Dk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=QgSn_7tAom0:-doig-qx-Dk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=QgSn_7tAom0:-doig-qx-Dk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=QgSn_7tAom0:-doig-qx-Dk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/QgSn_7tAom0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/</feedburner:origLink></item>
		<item>
		<title>Speed Tracer Server-side Tracing with Rack</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/cR2YZ7g1Hpk/</link>
		<comments>http://www.igvita.com/2010/07/19/speed-tracer-server-side-tracing-with-rack/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 19:42:20 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[chrome]]></category>

		<category><![CDATA[rack]]></category>

		<category><![CDATA[speedtracer]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1221</guid>
		<description><![CDATA[As anyone who has ever developed an interactive web app will know, Firebug (Firefox) and Inspector (Webkit) are your best friends. In fact, in many cases these tools are the "IDEs of choice" for manipulating the DOM, debugging JavaScript, and even working with CSS. However, have you ever wondered how many CPU cycles that script [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" src="http://www.igvita.com/posts/10/speedtracer-large.png" style="margin-right: 1em;">As anyone who has ever developed an interactive web app will know, <a href="http://getfirebug.com/">Firebug</a> (Firefox) and <a href="http://trac.webkit.org/wiki/WebInspector">Inspector</a> (Webkit) are your best friends. In fact, in many cases these tools are the "IDEs of choice" for manipulating the DOM, debugging JavaScript, and even working with CSS. However, have you ever wondered how many CPU cycles that script really took, or how much time the browser spent in reflow, as compared to just parsing the data? That's where <a href="http://code.google.com/webtoolkit/speedtracer/">Google's Speed Tracer</a> comes in. Provided as a Chrome extension, it instruments the <a href="http://code.google.com/p/v8/">V8 VM</a>, and the rest of the browser to provide detailed data about the GC cycles, painting, parsing, network resource loading and more.</p>
<p>The low level data provided by Speed Tracer finally allows us to peek under the covers to understand what the browser is actually doing - think strace, but for your browser. However, what if we could also bridge the gap between client-side and server-side tools? Wouldn't it be nice if we could go beyond the simple latency and response time reporting for network resources to viewing a full server-side log of what happened, all in one tool? Well, that's exactly what the Speed Tracer team launched at Google IO, so lets take a look at how it works!</p>
<h4><strong>Server-side tracing with SpeedTracer</strong></h4>
<p align="center"><img src="http://www.igvita.com/posts/10/speedtracer-workflow.png" /></p>
<p>The actual mechanics of getting server-side performance data into Speed Tracer are clever and simple. Whenever the browser receives a network response, it looks for the <strong>X-TraceUrl</strong> header, which specifies the relative URL and the unique ID of the trace for that specific request. From there, if the developer expands the network resource which provided the X-TraceUrl, Speed Tracer makes a request for the server-side trace, parses the JSON and surface it in the UI. This means that the server-side data is brought in on demand and does not affect the actual load times of your resources, and also that you need a mechanism to record, store, and serve these traces later.</p>
<h4><strong>Server side tracing with Rack & Ruby</strong></h4>
<p>The original announcement at Google IO demoed this new functionality on top of GWT and the <a href="http://www.springsource.com/products/tcserver">Spring TC server</a>. However, this same functionality is also easily extracted into a Rack middleware - which is what I did. In fact, here is a preview of sample trace from a Rails 3 application using <strong><a href="https://github.com/igrigorik/rack-speedtracer">rack-speedtracer</a></strong>:</p>
<p align="center"><img src="http://www.igvita.com/posts/10/speedtracer-rails.png" style="border: 1px solid #ccc;"/></p>
<p>The middleware takes care of providing the headers, persisting the traces, and then serving all the data back to Speed Tracer in the format it expects and understands under the hood. As a developer, you simply need to require the middleware, and then instrument your code where you want performance data to be recorded. Let's take a look at a simple configuration for a Rails 3 application:</p>
<p><a href="javascript:showme('9748_1');"> <b>> rails-speedtracer.rb</b></a>
<div style=" background:white;" id=9748_1>
<pre class="ruby"><span style="color:#008000; font-style:italic;"># in your Gemfile</span>
gem <span style="color:#996600;">'rack-speedtracer'</span>, <span style="color:#ff3333; font-weight:bold;">:require</span> =&gt; <span style="color:#996600;">'rack/speedtracer'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># in development.rb environment</span>
config.<span style="color:#9900CC;">middleware</span>.<span style="color:#9900CC;">use</span> <span style="color:#6666ff; font-weight:bold;">Rack::SpeedTracer</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># define a widgets controller</span>
<span style="color:#9966CC; font-weight:bold;">class</span> WidgetsController &lt; ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> index
    env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'st.tracer'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">run</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Widgets#index'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'st.tracer'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">run</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;ActiveRecord: Widgets.all&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        Widget.<span style="color:#9900CC;">all</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'st.tracer'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">run</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Render'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:text</span> =&gt; <span style="color:#996600;">'oh hai'</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<p><div class='download-link'>
							<a href='http://www.igvita.com/download.php?file=http://www.github.com/igrigorik/rack-speedtracer/tree/master/.git'><img alt='Download' class='leftalign' src='http://www.igvita.com/wp-content/plugins/dBeautifier/icons/github.png' /></a>
							<h4>
								<a href='http://www.igvita.com/download.php?file=http://www.github.com/igrigorik/rack-speedtracer/tree/master/.git'>rack-speedtracer (SpeedTracer Rack middleware)</a>
							</h4><p>Downloads: 220 File Size: 0.0 KB </p>
						</div></p>
<p>At the moment, you need to manually instrument your code to record this data, but there is also no reason why we couldn't automagically instrument Rails to provide detailed breakdowns of what is going on inside - <a href="http://github.com/brynary/rack-bug">rack/bug</a> is a great example. Of course, this functionality is not limited to Rails, and will work for <a href="https://github.com/igrigorik/rack-speedtracer/blob/master/examples/runner.rb">any Rack application</a>. There are still a few missing pieces in rack-speedtracer (<a href="http://www.github.com/igrigorik/rack-speedtracer">see readme</a> - patches are needed and welcome!) before you can deploy it in production, but it will work great for development purposes.</p>
<h4><strong>Towards unified client & server debugging</strong></h4>
<p>Having both the server-side and client-side performance data in a unified view can make our lives, as developers, an order of magnitude simpler - tired of correlating server logs with your browser yet? Having a mechanism to view this data on-demand, and in a single place is exciting, and I hope that the Speed Tracer team continues to innovate in this direction. It would be great to see more metadata about code locations, exceptions, object instantiation, and so on from within the same UI. But in the meantime, do <a href="http://code.google.com/webtoolkit/speedtracer/get-started.html#downloading">install it</a>, <a href="http://code.google.com/webtoolkit/speedtracer/get-started.html">play with it</a>, and give <a href="http://www.github.com/igrigorik/rack-speedtracer">rack-speedtracer</a> a try.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=cR2YZ7g1Hpk:ZNE46xPMyIA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=cR2YZ7g1Hpk:ZNE46xPMyIA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=cR2YZ7g1Hpk:ZNE46xPMyIA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=cR2YZ7g1Hpk:ZNE46xPMyIA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=cR2YZ7g1Hpk:ZNE46xPMyIA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=cR2YZ7g1Hpk:ZNE46xPMyIA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=cR2YZ7g1Hpk:ZNE46xPMyIA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=cR2YZ7g1Hpk:ZNE46xPMyIA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=cR2YZ7g1Hpk:ZNE46xPMyIA:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/cR2YZ7g1Hpk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/07/19/speed-tracer-server-side-tracing-with-rack/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/07/19/speed-tracer-server-side-tracing-with-rack/</feedburner:origLink></item>
		<item>
		<title>Weak Consistency and CAP Implications</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/H2zaSt5B2PU/</link>
		<comments>http://www.igvita.com/2010/06/24/weak-consistency-and-cap-implications/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 17:07:02 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[cap]]></category>

		<category><![CDATA[consistency]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1171</guid>
		<description><![CDATA[Migrating your web application from a single node to a distributed setup is always a deceivingly large architectural change. You may need to do it due to a resource constraint of a single machine, for better availability, to decouple components, or for a variety of other reasons. Under this new architecture, each node is on [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/cap-network.png"/>Migrating your web application from a single node to a distributed setup is always a deceivingly large architectural change. You may need to do it due to a resource constraint of a single machine, for better availability, to decouple components, or for a variety of other reasons. Under this new architecture, each node is on its own, and a network link is present to piece it all back together. So far so good, in fact, ideally we would also like for our new architecture to provide a few key properties: <em><strong>C</strong>onsistency</em> (no data conflicts), <em><strong>A</strong>vailability</em> (no single point of failure), and <em><strong>P</strong>artition tolerance</em> (maintain availability and consistency in light of network problems).</p>
<p>Problem is, the <a href="http://en.wikipedia.org/wiki/CAP_theorem">CAP theorem</a> proposed by Eric Brewer and later <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.20.1495&rep=rep1&type=pdf">proved by Seth Gilbert and Nancy Lynch</a>, shows that together, these three requirements are impossible to achieve at the same time. In other words, in a distributed system with an unreliable communications channel, it is impossible to achieve consistency and availability at the same time in the case of a network partition. Alas, such is the tradeoff.</p>
<h4><strong>"Pick Two" is too simple</strong></h4>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/cp-ca-pa.png"/>The <a href="http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf">original CAP conjecture</a> presented by Eric Brewer states that as architects, we can only pick two properties (CA, CP, or PA) at the same time, and many attempts have since been made to classify different distributed architectures into these three categories. Problem is, as <a href="http://dbmsmusings.blogspot.com/2010/04/problems-with-cap-and-yahoos-little.html">Daniel Abadi recently pointed out</a> (and <a href="http://twitter.com/eric_brewer/status/13057435836">Eric Brewer agrees</a>), the relationships between CA, CP and AP are not nearly as clear-cut as they appear on paper. In fact, any attempt to create a hard partitioning into these buckets seems to only <a href="http://blog.nahurst.com/visual-guide-to-nosql-systems">increase the confusion</a> since many of the systems can arbitrarily shift their properties with just a few operational tweaks - in the real world, it is rarely an all or nothing deal.</p>
<h4><strong>Focus on Consistency</strong></h4>
<p>Following some great conversations about CAP at a recent <a href="http://nosqlsummer.org/">NoSQL Summer</a> meetup and hours of trying to reconcile all the edge cases, it is clear that the CA <em>vs.</em> CP <em>vs.</em> PA model is, in fact, a poor representation of the implications of the CAP theorem - the simplicity of the model is nice, but in reality the actual design space requires more nuance. Specifically, instead of focusing on all three properties at once, it is more productive to first focus along the continuum of “data consistency” options: none, weak, and full.</p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/consistency-cap.png"/>On one extreme, a system can demand no consistency. For example, a clickstream application which is used for best effort personalization can easily tolerate a few missed clicks. In fact, the data may even be partitioned by data centre, geography, or server, such that depending on where you are, a different “context” is applied - from home, your search returns one set of results, from work, another! The advantage of such a system is that it is inherently highly available (HA) as it is a share nothing, best effort architecture.</p>
<p>On the other extreme, a system can demand full consistency across all participating nodes, which implies some communications protocol to reach a consensus. A canonical example is a “debit / credit”  scenario where full agreement across all nodes is required prior to any data write or read. In this scenario, all nodes maintain the exact same version of the data, but compromise HA in the process - if one node is down, or is in disagreement, the system is down.</p>
<h4><strong>CAP Implies Weak Consistency</strong></h4>
<p>Strong consistency and high availability are both desirable properties, however the CAP theorem shows that we can’t achieve both of these over an unreliable channel at once. Hence, CAP pushes us into a <em>“weak consistency”</em> model where dealing with failures is a fact of life. However, the good news is that we do have a gamut of possible strategies at our disposal.</p>
<p align="center"><img align="center" src="http://www.igvita.com/posts/10/cap-space.png"/></p>
<p>In case of a failure, your first choice could be to choose consistency over availability. In this scenario, if a <a href="http://en.wikipedia.org/wiki/Quorum_(Distributed_Systems)">quorum</a> can be reached, then one of the network partitions can remain available, while the second goes offline. Once the link between the two networks is restored, a simple data repair can take place - the minority partition is strictly behind, hence there are no possible data conflicts. Hence we sacrifice HA, but do continue to serve some of the clients.</p>
<p>On the other hand, we could lean towards availability over consistency. In this case, both sides can continue to accept reads and/or writes. Both sides of the partition remain available, and mechanisms such as <a href="http://en.wikipedia.org/wiki/Vector_clock">vector clocks</a> can be used to assist with conflict resolution (although, some conflicts will always require application level resolution). Repeatable reads, read-your-own-writes, and quorum updates are just a few of the examples of possible consistency <em>vs.</em> availability strategies in this scenario.</p>
<p>Hence, a simple corollary to the CAP theorem: <em>when choosing availability under the weak consistency model, multiple versions of a data object will be present, will require conflict resolution, and it is up to your application to determine what is an acceptable consistency tradeoff and a resolution strategy for each type of object</em>.</p>
<h4><strong>Speed of Light: Too Slow for PNUTS!</strong></h4>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/yahoo.png"/>Interestingly enough, dealing with network partitions is not the only case for adopting “weak consistency”. The <a href="http://portal.acm.org/citation.cfm?id=1454167">PNUTS</a> system deployed at Yahoo must deal with WAN replication of data between different continents, and unfortunately, the speed of light imposes some strict latency limits on the performance of such a system. In Yahoo’s case, the communications latency is enough of a performance barrier such that their system is configured, by default, to operate under the “choose availability, under weak consistency” model - think of latency as a pseudo-permanent network partition.</p>
<h4><strong>Architecting for Weak Consistency</strong></h4>
<p>Instead of arguing over CA <em>vs.</em> CP <em>vs.</em> PA, first determine the consistency model for your application: strong, weak, or shared nothing / best effort. Notice that this choice has nothing to do with the underlying technology, and everything with the demands and the types of data processed by your application. From there, if you land in the weak-consistency model (and you most likely will, if you have a distributed architecture), start thinking how you can deal with the inevitable data conflicts: will you lean towards consistency and some partial downtime, or will you optimize for availability and conflict resolution?</p>
<p>Finally, if you are working under weak consistency, it is also worth noting that it is not a matter of picking just a single strategy. Depending on the context, the application layer can choose a different set of requirements for each data object! Systems such as <a href="http://project-voldemort.com/">Voldemort</a>, <a href="http://cassandra.apache.org/">Cassandra</a>, and <a href="http://en.wikipedia.org/wiki/Dynamo_(storage_system)">Dynamo</a> all provide mechanisms to specify a desired level of consistency for each individual read and write. So, an order processing function can fail if it fails to establish a quorum (consistency over availability), while at the same time, a new user comment can be accepted by the same data store (availability over consistency).</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=H2zaSt5B2PU:ouBfDdYTHPM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=H2zaSt5B2PU:ouBfDdYTHPM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=H2zaSt5B2PU:ouBfDdYTHPM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=H2zaSt5B2PU:ouBfDdYTHPM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=H2zaSt5B2PU:ouBfDdYTHPM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=H2zaSt5B2PU:ouBfDdYTHPM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=H2zaSt5B2PU:ouBfDdYTHPM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=H2zaSt5B2PU:ouBfDdYTHPM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=H2zaSt5B2PU:ouBfDdYTHPM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/H2zaSt5B2PU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/06/24/weak-consistency-and-cap-implications/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/06/24/weak-consistency-and-cap-implications/</feedburner:origLink></item>
		<item>
		<title>Rails Performance Needs an Overhaul</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/mNpthf4nAys/</link>
		<comments>http://www.igvita.com/2010/06/07/rails-performance-needs-an-overhaul/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 14:32:27 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[performance]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1142</guid>
		<description><![CDATA[Browsers are getting faster; JavaScript frameworks are getting faster; MVC frameworks are getting faster; databases are getting faster. And yet, even with all of this innovation around us, it feels like there is massive gap when it comes to the end product of delivering an effective and scalable service as a developer: the performance of [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/drivetrain.png"/>Browsers are getting faster; JavaScript frameworks are getting faster; MVC frameworks are getting faster; databases are getting faster. And yet, even with all of this innovation around us, it feels like there is massive gap when it comes to the end product of delivering an effective and scalable service as a developer: the performance of most of our web stacks, when measured end to end is poor at best of times, and plain terrible in most.</p>
<p>The fact that a vanilla Rails application requires a dedicated worker with a <strong>50MB</strong> stack to render a login page is nothing short of absurd. There is nothing new about this, nor is this exclusive to Rails or a function of Ruby as a language - whatever language or web framework you are using, chances are, you are stuck with a similar problem. But <a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/">GIL or no GIL</a>, we ought to do better than that. Node.js is a recent innovator in the space, and as a community, we can either learn from it, or ignore it at our own peril.</p>
<h4><strong>Measuring End-to-End Performance</strong></h4>
<p align="center"><img align="center" src="http://www.igvita.com/posts/10/webstack.png"/></p>
<p>A modern web-service is composed of many moving components, all of which come together to create the final experience. First, you have to model your data layer, pick the database and then ensure that it can get your data in and out in the required amount of time - lots of innovation in this space thanks to the NoSQL movement. Then, we layer our MVC frameworks on top, and fight religious wars as developers on whose DSL is more beautiful - to me, Rails 3 deserves all the hype. On the user side, we are building faster browsers with blazing-fast JavaScript interpreters and CSS engines. However, the driveshaft (the app server) which connects the two pieces (the engine: data & MVC), and the front-end (the browser + DOM & JavaScript), is often just a checkbox in the deployment diagram. The problem is, this checkbox is also the reason why the ‘scalability’ story of our web frameworks is nothing short of terrible. </p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/rails-servers.png"/>It doesn't take much to construct a <a href="http://www.slideshare.net/igrigorik/beyond-gem-install-mysql-in-ruby/20">pathological example</a> where a popular framework (Rails), combined with a popular database (MySQL), and a popular app server (<a href="http://github.com/fauna/mongrel">Mongrel</a>) produce less than stellar results. Now the finger pointing begins. MySQL is more than capable of serving thousands of concurrent requests, the app server also claims to be threaded, and the framework even allows us to configure a database pool!</p>
<p>Except that, the database driver <a href="http://www.igvita.com/2008/10/27/scaling-activerecord-with-mysqlplus/">locks our VM</a>, and both the framework and the app server still have a few mutexes deep in their guts, which impose hard limits on the concurrency (read, serial processing). The problem is, this is the default behaviour! No wonder people <a href="https://www.google.com/search?hl=en&q=rails+is+slow&btnG=Search&aq=f&aqi=&aql=&oq=&gs_rfai=">complain about 'scalability'</a>. The other popular choices (<a href="http://www.modrails.com/">Passenger</a> / <a href="http://unicorn.bogomips.org/">Unicorn</a>) “<em>work around</em>” this problem by requiring dedicated VMs per request - that's not a feature, that's a bug!</p>
<h4><strong>The Rails Ecosystem</strong></h4>
<p>To be fair, we have come a long way since the days of WEBrick. In many ways, Mongrel made Rails viable, Rack gave us the much needed interface to become app-server independent, and the guys at Phusion gave us Passenger which both simplified the deployment, and made the resource allocation story moderately better. To complete the picture, Unicorn recently rediscovered the *nix IPC worker model, and is currently <a href="http://engineering.twitter.com/2010/03/unicorn-power.html">in use at Twitter</a>. Problem is, none of this is new (at best, we are iterating on the Apache 1.x to 2.x model), nor does it solve our underlying problem.</p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/nodejs.png"/>Turns out, while all the components are separate, and its great to treat them as such, we do need to look at the entire stack as one picture when it comes to performance: the database <a href="http://blog.phusion.nl/2010/06/10/making-ruby-threadable-properly-handling-context-switching-in-native-extensions/">driver needs to be smarter</a>, the framework should take advantage of the app servers capabilities, and the app server itself can't pretend to work in isolation.</p>
<p>If you are looking for a great working example of this concept in action, look no further than <a href="http://nodejs.org/">node.js</a>. There is nothing about node that can't be reproduced in Ruby or Python (<a href="http://github.com/eventmachine/eventmachine">EventMachine</a> and <a href="http://twistedmatrix.com/trac/">Twisted</a>), but the fact that the framework forces you to think and use the right components in place (fully async & non-blocking) is exactly why it is currently grabbing the mindshare of the early adopters. Rubyists, Pythonistas, and others can ignore this trend at their own peril. Moving forward, end-to-end performance and scalability of any framework will only become more important.</p>
<h4><strong>Fixing the "Scalability" story in Ruby</strong></h4>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/ruby-rails.png"/>The good news is, for every outlined problem, there is already a working solution. With a little extra work, the driver story is <a href="http://github.com/oldmoe/mysqlplus">easily</a> <a href="http://github.com/igrigorik/em-mysqlplus">addressed</a> (MySQL driver is just an example, the same story applies to virtually every other SQL/NoSQL driver), and the frameworks are steadily removing the bottlenecks one at a time.</p>
<p>After a <a href="http://en.oreilly.com/rails2010/public/schedule/detail/14096">few iterations at PostRank</a>, we rewrote some <a href="http://labs.postrank.com/">key drivers</a>, grabbed <a href="http://code.macournoyer.com/thin/">Thin</a> (evented app server), and made <a href="http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/">heavy use of continuations</a> in Ruby 1.9 to create our own API framework (<em>Goliath</em>) which is perfectly capable of serving hundreds of concurrent requests at a time from within a single Ruby VM. In fact, we even managed to avoid all the callback spaghetti that plagues node.js applications, which also means that the <a href="http://www.igvita.com/2010/04/15/non-blocking-activerecord-rails/">same continuation approach works just as well</a> with a vanilla Rails application. It just baffles me that this is not a solved problem already.</p>
</p>
<p>The state of art in the end-to-end Rails stack performance is not good enough. We need to fix that.</p>
<p class="download">Update: Thanks to <a href="http://twitter.com/greggpollack">Gregg Pollack</a> and his awesome team at <a href="http://envylabs.com/">Envylabs</a>, here is a recording of an updated and somewhat compressed version of the talk on this subject I gave at OSCON:</p>
<p align="center">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="545" height="451" id="viddler_cfadc37f"><param name="movie" value="http://www.viddler.com/player/cfadc37f/" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><embed src="http://www.viddler.com/player/cfadc37f/" width="545" height="451" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_cfadc37f"></embed></object></p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=mNpthf4nAys:vIPdnvbHiBM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=mNpthf4nAys:vIPdnvbHiBM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=mNpthf4nAys:vIPdnvbHiBM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=mNpthf4nAys:vIPdnvbHiBM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=mNpthf4nAys:vIPdnvbHiBM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=mNpthf4nAys:vIPdnvbHiBM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=mNpthf4nAys:vIPdnvbHiBM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=mNpthf4nAys:vIPdnvbHiBM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=mNpthf4nAys:vIPdnvbHiBM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/mNpthf4nAys" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/06/07/rails-performance-needs-an-overhaul/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/06/07/rails-performance-needs-an-overhaul/</feedburner:origLink></item>
		<item>
		<title>Scalable Work Queues with Beanstalk</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/B4Nf_wAjpVA/</link>
		<comments>http://www.igvita.com/2010/05/20/scalable-work-queues-with-beanstalk/#comments</comments>
		<pubDate>Thu, 20 May 2010 16:38:46 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[beanstalk]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1123</guid>
		<description><![CDATA[Any web application that reaches some critical mass eventually discovers that separation of services, where possible, is a great strategy for scaling the service. In fact, oftentimes a user action can be offloaded into a background task, which can be handled asynchronously while the user continues to explore the site. However, coordinating this workflow does [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/beanstalkd.png"/>Any web application that reaches some critical mass eventually discovers that separation of services, where possible, is a great strategy for scaling the service. In fact, oftentimes a user action can be offloaded into a background task, which can be handled asynchronously while the user continues to explore the site. However, coordinating this workflow does require some infrastructure: a message queue, or a work queue. The distinction between the two is subtle and blurry, but it does carry important architectural implications. Should you pick a messaging bus such as <a href="http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol">AMQP</a> or <a href="http://www.igvita.com/2009/11/10/consuming-xmpp-pubsub-in-ruby/">XMPP</a>, roll your own database backed system such as <a href="http://github.com/ahoward/bj">BJ</a>, go with <a href="http://github.com/blog/542-introducing-resque">Resque</a>, or evaluate the other three dozen variants available in every conceivable language?</p>
<p>Of course, there is no single answer to that question - it depends on your application. AMQP is a great <a href="http://www.igvita.com/2009/10/08/advanced-messaging-routing-with-amqp/">power tool for message routing</a>, but there are other systems that can do a better job at specific tasks. One of such tools is <a href="http://kr.github.com/beanstalkd/">Beanstalkd</a>, which is a simple, and a very fast work queue service rolled into a single binary - it is the memcached of work queues. Originally built to power the backend for Causes Facebook app, it is a mature and production ready <a href="http://github.com/kr/beanstalkd">open source project</a>. It just seems that not too many people talk about it, perhaps exactly because it works so well.</p>
<h4><strong>Beanstalkd Features & Recipes</strong></h4>
<p>Adam Wiggins recently published a <a href="http://adam.heroku.com/past/2010/4/24/beanstalk_a_simple_and_fast_queueing_backend/">great comparison</a> of Beanstalk to a few other work-queue services, and speed is where it stands out. A single instance of Beanstalk is perfectly capable of handling thousands of jobs a second (or more, depending on your job size) because it is an in-memory, event-driven system. Powered by <a href="http://www.monkey.org/~provos/libevent/">libevent</a> under the hood, it requires zero setup (launch and forget, ala memcached), optional log based persistence, an easily parsed ASCII protocol, and a rich set of tools for job management that go well beyond a simple FIFO work queue.</p>
<p>Out of the box, Beanstalk supports multiple <em>'tubes'</em> (work queues), which are created and deleted on demand. In turn, each job is associated with a single tube, and has a number of parameters: priority, time to run, delay, an id, and an opaque job body itself. </p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/beanstalk-workflow.png"/>Once a job is inserted into the work queue, the server returns an ID, which we can use to inspect the job. From there, the queue itself is actually a priority heap! Need to <strong>jump a head in line</strong>? Set a higher <a href="http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt#L132">priority</a> on the job and Beanstalk will do the rest. Or, <strong>what if your worker goes down</strong> while processing a job? Because you specified a <a href="http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt#L139">time to run</a> on the job, Beanstalk will monitor the checked out job and put it back on the work queue if the timeout expires - seamless recovery, nice. Does the worker need <strong>more time to complete the job</strong>? There is a '<a href="http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt#L303">touch</a>' command to notify the server to prolong the timeout. Have a bad job that you want to <strong>save for later inspection</strong>? Just <a href="http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt#L285">bury</a> it and take care of it later. Need to <strong>throttle all of the workers</strong>? You can <a href="http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt#L648">pause</a> the tube for a specified period of time. And there is more, do checkout the <a href="http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt">protocol specification</a>.</p>
<h4><strong>Beanstalk at PostRank: Chronos</strong></h4>
<p>At PostRank we have dozens of Beanstalk processes sprinkled throughout which are being used for job management within the same machine and coordination between entire clusters. The larger deployments, which are the front-line coordinators to our crawlers are serving 50+ million jobs on a daily basis (average job is several kb), without breaking a sweat. On average, each job is just several kilobytes, but the numbers add up, meaning that a pure memory system would require 60GB+ of RAM to make it work for our use case. That is where the Beanstalk ASCII protocol, good old MySQL, and a little Ruby come together to create our scheduling system: <em>Chronos</em>.</p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/pr-chronos.png"/>The idea behind Chronos is based on a simple observation: we have tens of millions of crawler jobs, each of which is repeated on a custom interval, but only a small portion of that entire set needs to be in memory to make the system run! So, out of that observation, two projects were born: <a href="http://github.com/dj2/em-jack">em-jack</a> and <a href="http://github.com/igrigorik/em-proxy">em-proxy</a>. EM-Jack is a Ruby Eventmachine client, which provides a simple mechanism to define <a href="http://github.com/dj2/em-jack/tree/master/lib/em-jack/handlers/">custom command handlers</a> that go beyond the native Beanstalk protocol. On the other hand, em-proxy is a protocol agnostic (<a href="http://en.wikipedia.org/wiki/Network_Layer">layer 3</a>) proxy, which allows us to intercept any TCP data stream and <a href="http://github.com/igrigorik/em-proxy/tree/master/examples/">manipulate it at will</a>.</p>
<p>So, instead of talking directly to Beanstalk, all the traffic is routed through our custom em-proxy (~150 LOC) which parses the Beanstalk protocol, intercepts custom commands, or simply inspects the "delay" parameter, and decides where the job should be routed: beanstalk or the MySQL instance. Jobs that are scheduled at least one hour into the future are persisted into the database, which significantly reduces the memory footprint. Finally, in the background, the upcoming jobs are silently loaded into beanstalk as their execution time approaches. Simple, reliable, scales well, and it gives us all the features available in Beanstalk for job management and coordination (plus persistence and replication of MySQL). A quick API demo:</p>
<p><a href="javascript:showme('1555_1');"> <b>> em-jack.rb</b></a>
<div style=" background:white;" id=1555_1>
<pre class="ruby">EM.<span style="color:#9900CC;">run</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  jack = <span style="color:#6666ff; font-weight:bold;">EMJack::Connection</span>.<span style="color:#9900CC;">new</span>
  r = jack.<span style="color:#9900CC;">put</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;my message&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:ttr</span> =&gt; <span style="color:#006666;">300</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |jobid| <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;put successful #{jobid}&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  j = jack.<span style="color:#9900CC;">reserve</span>
  j.<span style="color:#9900CC;">callback</span> <span style="color:#9966CC; font-weight:bold;">do</span> |job|
    <span style="color:#CC0066; font-weight:bold;">puts</span> job.<span style="color:#9900CC;">jobid</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> job.<span style="color:#9900CC;">body</span>
&nbsp;
    jack.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span>job<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Successfully deleted&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<p><div class='download-link'>
							<a href='http://www.igvita.com/download.php?file=http://www.github.com/dj2/em-jack/tree/master/.git'><img alt='Download' class='leftalign' src='http://www.igvita.com/wp-content/plugins/dBeautifier/icons/github.png' /></a>
							<h4>
								<a href='http://www.igvita.com/download.php?file=http://www.github.com/dj2/em-jack/tree/master/.git'>em-jack (An evented beanstalk client)</a>
							</h4><p>Downloads: 346 File Size: 0.0 KB </p>
						</div></p>
<h4><strong>Architecture Limitations and Alternatives</strong></h4>
<p>There is an abundance of different job and message queue systems, in part because they are so seemingly simple to write. However, if you ever tried to build your own, you will also know that the scaling and the features available in Beanstalk are non-trivial to replicate. However, there are a few limitations as well. Beanstalk does not currently support replication or any other form of high availability. Likewise, there is no native sharding (a few clients support it), or a native GUI. Other then that, it works, it is fast, it is easy to extend, and it is definitely worth a <a href="http://kr.github.com/beanstalkd/">test drive</a>.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=B4Nf_wAjpVA:f5K2EXqsjVo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=B4Nf_wAjpVA:f5K2EXqsjVo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=B4Nf_wAjpVA:f5K2EXqsjVo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=B4Nf_wAjpVA:f5K2EXqsjVo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=B4Nf_wAjpVA:f5K2EXqsjVo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=B4Nf_wAjpVA:f5K2EXqsjVo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=B4Nf_wAjpVA:f5K2EXqsjVo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=B4Nf_wAjpVA:f5K2EXqsjVo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=B4Nf_wAjpVA:f5K2EXqsjVo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/B4Nf_wAjpVA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/05/20/scalable-work-queues-with-beanstalk/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/05/20/scalable-work-queues-with-beanstalk/</feedburner:origLink></item>
		<item>
		<title>Distributed Coordination with Zookeeper</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/xdIGXMMlSWY/</link>
		<comments>http://www.igvita.com/2010/04/30/distributed-coordination-with-zookeeper/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 18:27:32 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[hadoop]]></category>

		<category><![CDATA[zookeeper]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1090</guid>
		<description><![CDATA[The Apache Hadoop project is an umbrella for a number of sub-projects, many of which are quite useful outside the Hadoop framework itself. Avro, for one, is a serialization framework with great performance and an API tailored for dynamic environments. Likewise, Zookeeper is a project incubated within the Hadoop ecosystem, but worth spending some time [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/zookeeper.png"/>The Apache Hadoop project is an umbrella for a number of sub-projects, many of which are quite useful outside the Hadoop framework itself. Avro, for one, is a serialization framework with <a href="http://www.igvita.com/2010/02/16/data-serialization-rpc-with-avro-ruby/">great performance and an API</a> tailored for dynamic environments. Likewise, <a href="http://hadoop.apache.org/zookeeper/">Zookeeper</a> is a project incubated within the Hadoop ecosystem, but worth spending some time with due its wide applicability for building distributed systems.</p>
<p>Back in 2006, Google <a href="http://labs.google.com/papers/chubby.html">published a paper on "Chubby"</a>, a distributed lock service which gained wide adoption within their data centers. Zookeeper, not surprisingly, is a close clone of Chubby designed to fulfill many of the same roles for HDFS and other Hadoop infrastructure. The original paper from Google offers a number of interesting insights, but the biggest takeaway is: Chubby and Zookeeper are both much more than a distributed lock service. In fact, it may be better to think of them as implementations of highly available, distributed metadata filesystems.</p>
<h4><strong>Zookeeper as a Metadata Filesystem</strong></h4>
<p>At its core, Zookeeper is modeled after a straightforward, tree based, file system API. A client is able to create a node, store up to 1MB of data with it, and also associate as many children nodes as they wish. However, there are no renames, soft or hard links, and no append semantics. Instead, by dropping those features, Zookeeper guarantees completely ordered updates, data versioning, conditional updates (CAS), as well as, a few more advanced features such as "ephemeral nodes", "generated names", and an async notification ("watch") API.</p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/fs-zookeeper.png"/>Now, this may seem like a grab bag of features, but don't forget that all of this is functionality is exposed as a remote service. Meaning, any network client can create a node, update associated metadata, submit a conditional update, or request an async notification via a <em><strong>"watch"</strong></em> request, which essentially mirrors the <a href="http://en.wikipedia.org/wiki/Inotify">inotify</a> functionality exposed in the Linux kernel.</p>
<p>Likewise, to make things easier, a client can request for Zookeeper to generate the node name to avoid collisions (e.g. to allow multiple concurrent clients to create nodes within same namespace without any collisions). And last but not least, what if you wanted to create a node, which only existed for the lifetime of your connection to Zookeper? That's what <em><strong>"ephemeral nodes"</strong></em> are for - essentially, they give you <a href="http://en.wikipedia.org/wiki/Presence_information">presence</a>. Now, put all of these things together, and you have a powerful toolkit to solve many problems in distributed computing.</p>
<h4><strong>Zookeeper: Distributed Architecture</strong></h4>
<p>Of course, if we are to deploy Zookeeper in a distributed environment, we have to think about both the availability and scalability of the service. At Google, Chubby runs on a minimum of five machines, to guarantee high availability, and also transparently provides a built-in master election and failover mechanisms. Not surprisingly, Zookeeper is built under the same model. Given a cluster of Zookeeper servers, only one acts as a leader, whose role is to accept and coordinate all writes (via a quorum). All other servers are direct, read-only replicas of the master. This way, if the master goes down, any other server can pick up the slack and immediately continue serving requests. As an interesting sidenote, Zookeeper allows the standby servers to serve reads, whereas Google's Chubby directs all reads and writes to the single master - apparently a single server can handle all the load!</p>
<p align="center"><img src="http://www.igvita.com/posts/10/zoo-architecture.png"/></p>
<p>The one limitation of this design is that every node in the cluster is an exact replica - there is no sharding and hence the capacity of the service is limited by the size of an individual machine. The Google paper briefly mentions a possible logical sharding scheme, but in practice, it seems that they had no need for such a feature just yet. Now let's take a look at the applications.</p>
<h4><strong>Applications on top of Zookeeper & Chubby</strong></h4>
<p>Within the Hadoop/HBase umbrella, Zookeeper is used to manage master election and store other process metadata. Hadoop/HBase competitors love to point to Zookeeper as a SPOF (single point of failure), but in reality, given the backing architecture this seems to be too often over-dramatized. Perhaps even more interestingly, as the Google paper mentions, Chubby has in effect replaced DNS within the Google infrastructure!</p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/hadoop.png"/>By allowing any client to access and store metadata, you can imagine a simple case where a cluster of databases can share their <strong>configuration information</strong> (sharding functions, system configs, etc), within a single namespace: <em>"/app/database/config"</em>. In fact, each database could request a watch on that node, and receive <strong>real-time notifications</strong> whenever someone updates the data (for example, a data rebalancing due to adding a new database into the cluster). However, that is just the beginning. Since "ephemeral nodes" provide basic presence information, by having each worker machine register with Zookeeper, we can perform <strong>real-time group membership queries</strong> to see which nodes are online, and perhaps even figure out what they are currently doing.</p>
<p>What about consensus? With a little extra work we can also leverage the data versioning and notifications APIs to build distributed primitives such as <a href="http://wiki.apache.org/hadoop/ZooKeeper/Tutorial">worker queues and barriers</a>. From there, once we have locks and consensus, we can tackle virtually any distributed problem: master election, quorum commits, and so on. In other words, it becomes your swiss army knife for coordinating distributed services.</p>
<h4><strong>Working with Zookeeper</strong></h4>
<p>Getting started with Zookeeper is <a href="http://hadoop.apache.org/zookeeper/docs/current/zookeeperStarted.html">relatively straightforward</a>: download the source, load the jar file, and you're ready to experiment in a single node mode. From there, you can try interacting with Zookeeper via a simple shell provided with the project:</p>
<blockquote><p>
<strong># create root node for an application, with world read-write permissions</strong><br />
[zk: localhost:2181(CONNECTED) 2] create /myapp description world:anyone:cdrw<br />
Created /myapp</p>
<p><strong># Create a sequential (-s) and ephemeral (-e) node</strong><br />
[zk: localhost:2181(CONNECTED) 6] create -s -e /myapp/server- appserver world:anyone:cdrw<br />
Created /myapp/server-0000000001</p>
<p><strong># List current nodes</strong><br />
[zk: localhost:2181(CONNECTED) 5] ls /myapp<br />
=> [server-0000000000]</p>
<p><strong># Fetch data for one of the nodes</strong><br />
[zk: localhost:2181(CONNECTED) 8] get /myapp/server-0000000001<br />
appserver
</p></blockquote>
<p><div class='download-link'>
							<a href='http://www.igvita.com/download.php?file=http://www.github.com/apache/zookeeper/tree/trunk/.git'><img alt='Download' class='leftalign' src='http://www.igvita.com/wp-content/plugins/dBeautifier/icons/github.png' /></a>
							<h4>
								<a href='http://www.igvita.com/download.php?file=http://www.github.com/apache/zookeeper/tree/trunk/.git'>zookeeper (Mirror of Apache Hadoop ZooKeeper)</a>
							</h4><p>Downloads: 400 File Size: 0.0 KB </p>
						</div></p>
<p>Similarly, we can perform all of the same actions directly from Ruby via several libraries. The <a href="http://github.com/emaland/zookeeper_client">zookeeper_client gem</a> provides bindings against the C-based API, but unfortunately it doesn't support some of the more advanced features such as watches and asynchronous notifications. Alternatively, the <a href="http://github.com/smingins/zookeeper">zookeeper gem by Shane Mingins</a> provides a fully featured JRuby version, which seems to cover the <a href="http://gist.github.com/383140">entire API</a>.</p>
<p> And if you are feeling adventurous, you could even try the experimental <a href="https://issues.apache.org/jira/browse/ZOOKEEPER-25?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel">FUSE mount</a>, or the <a href="https://issues.apache.org/jira/browse/ZOOKEEPER-36">REST server</a> for Zookeeper. For some ideas, check out <a href="http://github.com/grantr/game_warden/blob/master/example/config.rb">game_warden</a> (Ruby DSL for dynamic configuration management) built around zookeeper, and a few <a href="http://highscalability.com/blog/2008/7/15/zookeeper-a-reliable-scalable-distributed-coordination-syste.html">other</a> <a href="http://www.cloudera.com/blog/2009/05/building-a-distributed-concurrent-queue-with-apache-zookeeper/">articles</a> on the project. Zookeeper is already in use in a number of projects and companies (Digg, LinkedIn, Wall Street), so you are in good company.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=xdIGXMMlSWY:aKz85EVnOzM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=xdIGXMMlSWY:aKz85EVnOzM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=xdIGXMMlSWY:aKz85EVnOzM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=xdIGXMMlSWY:aKz85EVnOzM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=xdIGXMMlSWY:aKz85EVnOzM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=xdIGXMMlSWY:aKz85EVnOzM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=xdIGXMMlSWY:aKz85EVnOzM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=xdIGXMMlSWY:aKz85EVnOzM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=xdIGXMMlSWY:aKz85EVnOzM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/xdIGXMMlSWY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/04/30/distributed-coordination-with-zookeeper/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/04/30/distributed-coordination-with-zookeeper/</feedburner:origLink></item>
		<item>
		<title>Non-blocking ActiveRecord &amp; Rails</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/raYgotyiVoY/</link>
		<comments>http://www.igvita.com/2010/04/15/non-blocking-activerecord-rails/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 20:39:41 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[activerecord]]></category>

		<category><![CDATA[eventmachine]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1071</guid>
		<description><![CDATA[ Rails and MySQL go hand in hand. ActiveRecord is perfectly capable of using a number of different databases but MySQL is by far the most popular choice for production deployments. And therein lies a dirty secret: when it comes to performance and 'scalability' of the framework, the Ruby MySQL gem is a serious offender. [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/08/rails.png"/> Rails and MySQL go hand in hand. ActiveRecord is perfectly capable of using a number of different databases but MySQL is by far the most popular choice for production deployments. And therein lies a dirty secret: when it comes to performance and <em>'scalability'</em> of the framework, the Ruby MySQL gem is a serious offender. The presence of the GIL means that <a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/">concurrency is already somewhat of a myth in the Ruby VM</a>, but the architecture of the driver makes the problem even worse. Let's take a look under the hood.</p>
<h4><strong>Dissecting Ruby MySQL drivers</strong></h4>
<p>The native mysql gem many of us use in production was designed to expose a blocking API: you issue a SQL query, and the library blocks until the server returns a response. So far so good, but unfortunately it also introduces a nasty side effect. Because it blocks inside of the native code (inside <strong>mysql_real_query()</strong> C function), the entire Ruby VM is frozen while we wait for the response. So, if you query happens to have taken several seconds, it means that no other block, fiber, or thread will be executed by the Ruby VM. Ever wondered why your threaded Mongrel server never really flexed its threaded muscle? Well, now you know.</p>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/mysql-logo.png"/> Fortunately, the little known <a href="http://github.com/oldmoe/mysqlplus">mysqlplus gem</a> addresses the immediate problem. Instead of using a single blocking call, it forwards the query to the server, and then starts <em>polling</em> for the response. For the curious, there are also two implementations, one in <a href="http://github.com/oldmoe/mysqlplus/blob/master/lib/mysqlplus.rb#L11">pure Ruby</a> with a select loop, and a native (C) one which uses <a href="http://github.com/oldmoe/mysqlplus/blob/master/ext/mysql.c#L1140">rb_thread_select</a>. The benefit? Well, now you can have multiple threads execute database queries without blocking the entire VM! In fact, with a little extra work, we can even get some <a href="http://www.igvita.com/2008/10/27/scaling-activerecord-with-mysqlplus/">concurrency out of ActiveRecord</a>.</p>
<p>However, we could even drop threads in our quest for concurrency! Instead of making every thread poll on a socket, we could pass each of those sockets to a single event loop (EventMachine) library, and let it handle all the IO scheduling for us: <em>gem install <a href="http://github.com/igrigorik/em-mysqlplus">em-mysqlplus</a></em>. Same API, in fact, it uses mysqlplus under the covers, but now every query has a callback for true non-blocking database access. Take a look at a few examples in the slides:</p>
<div style="width:600px" id="__ss_3737756"><object width="600" height="490"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mysql-100415123033-phpapp02&rel=0&stripped_title=beyond-gem-install-mysql-in-ruby" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mysql-100415123033-phpapp02&rel=0&stripped_title=beyond-gem-install-mysql-in-ruby" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="600" height="490"></embed></object></div>
<h4><strong>Non-blocking Rails with MySQL</strong></h4>
<p>Now we come around full circle. The downside of a true asynchronous library is that it requires callbacks, spaghetti code and a fully asynchronous stack. Thankfully, we already have <a href="http://code.macournoyer.com/thin/">Thin</a> for our async app server, and with the introduction of Fibers in Ruby 1.9, we can wrap our asynchronous driver to <a href="http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/">behave just as if it had a blocking API</a>.</p>
<p>So, we install <em>em-mysqlplus</em>, require <a href="http://github.com/igrigorik/em-synchrony">em-synchrony</a> to emulate the 'blocking api', implement an <a href="http://github.com/igrigorik/em-mysqlplus/blob/activerecord/lib/active_record/connection_adapters/em_mysqlplus_adapter.rb">activerecord adapter</a>, and we finally have a fully <a href="http://github.com/igrigorik/em-mysqlplus/blob/activerecord/spec/activerecord_spec.rb#L45">non-blocking ActiveRecord driver</a> which we can drop into our Rails app! Well, almost, a few other modifications: Rails provides a threaded <a href="http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html">ConnectionPool</a>, which we need to replace with a Fiber aware one, and finally, we need to disable the built in Mutex (hap tip to Mike Perham for doing all the <a href="http://www.mikeperham.com/2010/04/03/introducing-phat-an-asynchronous-rails-app/">dirty work for us</a>). Now let's give it a try:</p>
<p><a href="javascript:showme('4193_1');"> <b>> widgets_controller.rb</b></a>
<div style=" background:white;" id=4193_1>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> WidgetsController &lt; ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> index
    Widget.<span style="color:#9900CC;">find_by_sql</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;select sleep(1)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    render <span style="color:#ff3333; font-weight:bold;">:text</span> =&gt; <span style="color:#996600;">&quot;Oh hai&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<blockquote><p>
<strong>thin -D start</strong><br />
<strong>ab -c 5 -n 10 http://127.0.0.1/widgets/</strong></p>
<p>Server Software:        thin<br />
Server Hostname:        127.0.0.1<br />
Server Port:            3000</p>
<p>Concurrency Level:      5<br />
<strong>Time taken for tests:   2.210 seconds</strong><br />
Complete requests:      10<br />
Requests per second:    4.53 [#/sec] (mean)
</p></blockquote>
<p>Our widget action simulates a blocking one-second query, we start up a <strong>single</strong> thin server, and run an ab test against it: 10 requests, with a max concurrency of 5. And as you can see, the test finishes in just slightly over 2 seconds!</p>
<h4><strong>Rails 3, Ruby 1.9 and Drizzle</strong></h4>
<p><img align="left" style="margin-right: 1em;" src="http://www.igvita.com/posts/10/ruby-ror-drizzle.png"/>By mid summer we will see production releases of Rails 3, Ruby 1.9, and Drizzle, and that convergence is worth paying attention to. Both Rails 3 and Ruby 1.9 offer raw performance improvements across the board. In the meantime, Drizzle already provides a <a href="http://github.com/jakedouglas/libdrizzle-ruby-ffi">fully async libdrizzle driver</a> (talks to MySQL & Drizzle) which we could adopt to future proof our applications. Combine all three with a fibered ActiveRecord driver, an async application server such as Thin, and we could make some serious steps forward when it comes to performance of Rails: significantly lower memory footprint and much better performance across the board.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=raYgotyiVoY:A7puq9APsNk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=raYgotyiVoY:A7puq9APsNk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=raYgotyiVoY:A7puq9APsNk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=raYgotyiVoY:A7puq9APsNk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=raYgotyiVoY:A7puq9APsNk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=raYgotyiVoY:A7puq9APsNk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=raYgotyiVoY:A7puq9APsNk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=raYgotyiVoY:A7puq9APsNk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=raYgotyiVoY:A7puq9APsNk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/raYgotyiVoY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/04/15/non-blocking-activerecord-rails/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/04/15/non-blocking-activerecord-rails/</feedburner:origLink></item>
		<item>
		<title>Untangling Evented Code with Ruby Fibers</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/Wevsarq2Xeo/</link>
		<comments>http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 16:50:45 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[eventmachine]]></category>

		<category><![CDATA[fibers]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1043</guid>
		<description><![CDATA[Event-driven programming requires a mind-shift in how you architect the program, and oftentimes directly affects the choice of language, drivers, and even frameworks you can use. Most commonly found in highly interactive applications (GUI, network servers, etc), it usually implements the reactor pattern to handle concurrency in favor of threads: the “reactor” is a main [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" src="http://www.igvita.com/posts/10/em-synchrony.png" style="margin-right: 1em;"><a href="http://en.wikipedia.org/wiki/Event-driven_programming">Event-driven programming</a> requires a mind-shift in how you architect the program, and oftentimes directly affects the choice of language, drivers, and even frameworks you can use. Most commonly found in highly interactive applications (GUI, network servers, etc), it usually implements the <a href="http://en.wikipedia.org/wiki/Reactor_pattern">reactor pattern</a> to handle concurrency in favor of threads: the “reactor” is a main loop which is responsible for receiving all inbound events (network IO, filesystem, IPC, etc) and demultiplexing them to appropriate handlers or callbacks.</p>
<p>Turns out, the reactor pattern performs extremely well under heavy loads (<a href="http://www.kegel.com/c10k.html">C10K challenge</a>), hence the continuous rise in adoption (<a href="http://wiki.nginx.org/Main">Nginx</a>, <a href="http://kr.github.com/beanstalkd/">Beanstalkd</a>, <a href="http://github.com/eventmachine/eventmachine">EventMachine</a>, <a href="http://twistedmatrix.com/trac/">Twisted</a>, <a href="http://nodejs.org/">Node.js</a>), but it does have its downsides: it requires reactor-aware libraries, still relies on background processing capabilities for long running computations, and last but not least, once you have nested several callbacks, it results in much more complicated code. Functional purists will disagree with the last statement – after all, we all love JavaScript, and node.js is the new hot thing on the block – but what if we could write event driven code without the added complexity imposed by hundreds of nested callbacks?</p>
<h4><strong>Accidental Complexity of Event-Driven Code</strong></h4>
<p>Anyone who has written a non-trivial event driven application will be familiar with the following pattern: you often start reading your code bottom-up and then navigate your way up the callback chain. In addition, since there is no single execution context, each callback requires its own nested exception handling, which adds to the complexity - debugging is non-trivial, to say the least. Of course, this is usually not too bad in a context of a simple demo, but it also quickly spirals out of control.</p>
<p><a href="javascript:showme('942_1');"> <b>> em-callbacks.rb</b></a>
<div style=" background:white;" id=942_1>
<pre class="ruby">EventMachine.<span style="color:#9900CC;">run</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
  page = <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://google.ca/'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">get</span>
  page.<span style="color:#9900CC;">errback</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Google is down! terminate?&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  page.<span style="color:#9900CC;">callback</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    about = <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://google.ca/search?q=eventmachine'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">get</span>
    about.<span style="color:#9900CC;">callback</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#008000; font-style:italic;"># callback nesting, ad infinitum }</span>
    about.<span style="color:#9900CC;">errback</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#008000; font-style:italic;"># error-handling code }</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;</pre>
</div>
<p>Call me old-fashioned, but I much prefer the if-then-else control flow, with top-down execution and code I can actually read without callback gymnastics. And as luck would have it, turns out these are not inconsistent requirements in Ruby 1.9. With the introduction of Fibers, our applications can do <a href="http://www.igvita.com/2009/05/13/fibers-cooperative-scheduling-in-ruby/">fully-cooperative scheduling</a> (worth a re-read to make sense of the rest), which with a little extra work also means that we can abstract much of the complexity of event driven programming while maintaining all of its benefits!</p>
<h4><strong>Fibers & EventMachine: under the hood</strong></h4>
<p><a href="http://ruby-doc.org/core-1.9/classes/Fiber.html">Ruby 1.9 Fibers</a> are a means of creating code blocks which can be paused and resumed by our application (think lightweight threads, minus the thread scheduler and less overhead). Each fiber comes with a small 4KB stack, which makes them <a href="http://oldmoe.blogspot.com/2008/08/ruby-fibers-vs-ruby-threads.html">cheap to spin up</a>, pause and resume. Best of all, a fiber can yield the control and wait until someone else resumes it. I bet you see where we're going: start an async operation, yield the fiber, and then make the callback resume the fiber once the operation is complete. Let's wrap our async em-http client as an example:</p>
<p><a href="javascript:showme('942_2');"> <b>> em-fiber-wrap.rb</b></a>
<div style=" background:white;" id=942_2>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> http_get<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
  f = Fiber.<span style="color:#9900CC;">current</span>
  http = <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">get</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># resume fiber once http call is done</span>
  http.<span style="color:#9900CC;">callback</span> <span style="color:#006600; font-weight:bold;">&#123;</span> f.<span style="color:#9900CC;">resume</span><span style="color:#006600; font-weight:bold;">&#40;</span>http<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  http.<span style="color:#9900CC;">errback</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> f.<span style="color:#9900CC;">resume</span><span style="color:#006600; font-weight:bold;">&#40;</span>http<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  <span style="color:#0000FF; font-weight:bold;">return</span> Fiber.<span style="color:#9966CC; font-weight:bold;">yield</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
EventMachine.<span style="color:#9900CC;">run</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  Fiber.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#123;</span>
    page = http_get<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://www.google.com/'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Fetched page: #{page.response_header.status}&quot;</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">if</span> page
      page = http_get<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://www.google.com/search?q=eventmachine'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Fetched page 2: #{page.response_header.status}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">resume</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<p>First thing to notice is that we are now executing our asynchronous code within a fiber (<em>Fiber.new{}.resume</em>), and our http_get method sets up the call, assigns the callbacks and then immediately yields control as it tries to return from the function. From there, EventMachine takes over, fetches the data in the background, and then calls the callback method, which in turn resumes our fiber, passing it the actual response. A little bit of fiber gymnastics, but it means that our original code with nested callbacks can now be unwound into a regular top-down execution context with if-then-else control flow. Not bad!</p>
<h4><strong>EM-Synchrony: Evented Code With Less Pain</strong></h4>
<p>Of course, we wouldn't gain much if the net effect of introducing fibers into our event driven code was swapping callbacks for fiber gymnastics. Thankfully, we can do better because much of the underlying implementation can be easily abstracted at the level of the driver. Let's take a look at our new helper library, <strong>em-synchrony</strong>:</p>
<p><a href="javascript:showme('942_3');"> <b>> em-synchrony.rb</b></a>
<div style=" background:white;" id=942_3>
<pre class="ruby">EventMachine.<span style="color:#9900CC;">synchrony</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  page = <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://www.google.com&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">get</span>
&nbsp;
  <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;No callbacks! Fetched page: #{page}&quot;</span>
  EventMachine.<span style="color:#9900CC;">stop</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<p>Instead of invoking the default EM.run block, we call EM.synchrony, which in turn wraps our execution into a Ruby fiber behind the scenes. From there, the library also provides ready-made, fiber aware classes for some of the most common use cases (http: <a href="http://github.com/igrigorik/em-http-request">em-http-request</a>, mysql: <a href="http://github.com/igrigorik/em-mysqlplus">em-mysqlplus</a>, and memcached: <a href="http://github.com/astro/remcached">remcached</a>), as well as, a fiber aware <a href="https://github.com/igrigorik/em-synchrony/blob/master/spec/connection_pool_spec.rb">connection pool</a>, <a href="https://github.com/igrigorik/em-synchrony/blob/master/spec/iterator_spec.rb">iterator</a> for concurrency control, and a multi-request interface. Let's take a look at an example which flexes all of the above:</p>
<p><a href="javascript:showme('942_4');"> <b>> em-synchrony-ex.rb</b></a>
<div style=" background:white;" id=942_4>
<pre class="ruby">EM.<span style="color:#9900CC;">synchrony</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># open 4 concurrent MySQL connections</span>
  db = <span style="color:#6666ff; font-weight:bold;">EventMachine::Synchrony::ConnectionPool</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>size: <span style="color:#006666;">4</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#6666ff; font-weight:bold;">EventMachine::MySQL</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>host: <span style="color:#996600;">&quot;localhost&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># perform 4 http requests in parallel, and collect responses</span>
  multi = <span style="color:#6666ff; font-weight:bold;">EventMachine::Synchrony::Multi</span>.<span style="color:#9900CC;">new</span>
  multi.<span style="color:#9900CC;">add</span> <span style="color:#ff3333; font-weight:bold;">:page1</span>, <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://service.com/page1&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">aget</span>
  multi.<span style="color:#9900CC;">add</span> <span style="color:#ff3333; font-weight:bold;">:page2</span>, <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://service.com/page2&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">aget</span>
  multi.<span style="color:#9900CC;">add</span> <span style="color:#ff3333; font-weight:bold;">:page3</span>, <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://service.com/page3&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">aget</span>
  multi.<span style="color:#9900CC;">add</span> <span style="color:#ff3333; font-weight:bold;">:page4</span>, <span style="color:#6666ff; font-weight:bold;">EventMachine::HttpRequest</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://service.com/page4&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">aget</span>
  data = multi.<span style="color:#9900CC;">perform</span>.<span style="color:#9900CC;">responses</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:callback</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">values</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># insert fetched HTTP data into a mysql database, using at most 2 connections at a time</span>
  <span style="color:#008000; font-style:italic;"># - note that we're writing async code within the iterator!</span>
  <span style="color:#6666ff; font-weight:bold;">EM::Synchrony::Iterator</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>data, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |page, iter|
    db.<span style="color:#9900CC;">aquery</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;INSERT INTO table (data) VALUES(#{page});&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    db.<span style="color:#9900CC;">callback</span> <span style="color:#006600; font-weight:bold;">&#123;</span> iter.<span style="color:#0000FF; font-weight:bold;">return</span><span style="color:#006600; font-weight:bold;">&#40;</span>http<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;All done! Stopping event loop.&quot;</span>
  EventMachine.<span style="color:#9900CC;">stop</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
</div>
<p><div class='download-link'>
							<a href='http://www.igvita.com/download.php?file=http://www.github.com/igrigorik/em-synchrony/tree/master/.git'><img alt='Download' class='leftalign' src='http://www.igvita.com/wp-content/plugins/dBeautifier/icons/github.png' /></a>
							<h4>
								<a href='http://www.igvita.com/download.php?file=http://www.github.com/igrigorik/em-synchrony/tree/master/.git'>em-synchrony (Fiber aware EventMachine)</a>
							</h4><p>Downloads: 408 File Size: 0.0 KB </p>
						</div></p>
<p>Synchrony implements a common pattern: original asynchronous methods which return a deferrable object are aliased with <strong>"a"</strong> prefix (<em>.get</em> becomes <em>.aget</em>, <em>.query</em> becomes <em>.aquery</em>) to indicate that they are asynchronous, and the fiber aware methods take their place as the defaults. This way, you can still mix sync and async code all in the same context (within an iterator, for example). For more examples of em-synchrony in action, take a look at the <a href="https://github.com/igrigorik/em-synchrony/tree/master/spec/">specs provided within the library itself</a>.</p>
<h4><strong>Towards Scalable & Manageable Event-Driven Code</strong></h4>
<p><img align="left" src="http://www.igvita.com/posts/10/ruby-19-box.png" style="margin-right: 1em;">Event driven programming does not have to be complicated. With a little help from Ruby 1.9 much of the complexity is easily abstracted, which means that we can have all the benefits of event-driven IO, without any of the overhead of a thread scheduler or complicated code. Node.js, Twisted, and other reactor frameworks have a lot going for them, but the combination of EventMachine and Ruby 1.9, to me, is a clear winner.</p>
<p>We should also mention that fibers have been <a href="http://timetobleed.com/fibers-implemented-for-ruby-1867/">ported to Ruby 1.8</a>, but due to their implementation on top of green threads they incur much larger overhead - in other words, this is your reason to switch to Ruby 1.9! And last but not least, fibers or not, don't forget that <a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/">Ruby 1.9 still has a GIL</a> which means that only one CPU core will be used. Until we see MVM (multi-VM) support, the solution is simply to run multiple reactors (one or more for each core).</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=Wevsarq2Xeo:PBXN5o44kkQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=Wevsarq2Xeo:PBXN5o44kkQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=Wevsarq2Xeo:PBXN5o44kkQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=Wevsarq2Xeo:PBXN5o44kkQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=Wevsarq2Xeo:PBXN5o44kkQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=Wevsarq2Xeo:PBXN5o44kkQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=Wevsarq2Xeo:PBXN5o44kkQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=Wevsarq2Xeo:PBXN5o44kkQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=Wevsarq2Xeo:PBXN5o44kkQ:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/Wevsarq2Xeo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/</feedburner:origLink></item>
		<item>
		<title>Schema-Free MySQL vs NoSQL</title>
		<link>http://feeds.igvita.com/~r/igvita/~3/syizv-mDxYU/</link>
		<comments>http://www.igvita.com/2010/03/01/schema-free-mysql-vs-nosql/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 18:55:02 +0000</pubDate>
		<dc:creator>Ilya Grigorik</dc:creator>
		
		<category><![CDATA[Databases]]></category>

		<category><![CDATA[eventmachine]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://www.igvita.com/?p=1017</guid>
		<description><![CDATA[Amidst the cambrian explosion of alternative database engines (aka, NoSQL) it is almost too easy to lose sight of the fact that the more established solutions, such as relational databases, still have a lot to offer: stable and proven code base, drivers and tools for every conceivable language, and more features than any DBA cares [...]]]></description>
			<content:encoded><![CDATA[<p><img align="left" src="http://www.igvita.com/posts/10/cambrian-db.png" style="margin-right: 1em;">Amidst the cambrian explosion of alternative database engines (aka, NoSQL) it is almost too easy to lose sight of the fact that the more established solutions, such as relational databases, still have a lot to offer: stable and proven code base, drivers and tools for every conceivable language, and more features than any DBA cares to learn about. Not to mention that relational or not, they often times perform just as well as any other single instance key-value store when faced with large datasets - hence the reason why <a href="http://riak.basho.com/">Riak</a>, <a href="http://project-voldemort.com/">Voldemort</a> and others use InnoDB as their data stores.  Granted, the “feature bloat” is also the reason why a rewrite can be a good idea, but it also feels like this gray zone is too often overlooked in the NoSQL community - just because you are “NoSQL” does not mean you have to throw away years of work put into relational databases.</p>
<p>Setting aside the fact that we are yet to define what “NoSQL” actually is, some of the attributes that we commonly glob under this label are: document based, schema-free, distributed and “scalable”. The fact that being distributed and being scalable are not one and the same is a subject for another post, instead let’s take a closer look at what schema-free and document-based actually means. In fact, let me jump ahead: I am genuinely surprised that we are yet to see a schema-free engine built on top of MySQL. I know, I know, but suspend you disbelief for a second, because it is not as outrageous as it sounds.</p>
<h4><strong>Document Based: a Double Edged Sword</strong></h4>
<p>The <a href="http://en.wikipedia.org/wiki/Database_normalization#Objectives_of_normalization">original reason</a> for and the benefit of the relational model is that by constraining the data schema (read, eliminating structural complexity of the data, or decomposing it into relations), you actually gain power and flexibility in the types of queries you can execute against your database. Said another way, normalized data design allows us to have a <a href="http://en.wikipedia.org/wiki/Sql">general-purpose query language</a>, which allows for queries whose parameters we do not even know at design time, whereas denormalized designs do not. What we loose in flexibility of our data structures, we gain in our ability to interact with the data. Hence, in theory, if you have no way to anticipate the types of queries in the future, a relation model is your best bet. Lose some, win some, chose your poison.</p>
<p><img align="left" src="http://www.igvita.com/posts/10/nested-data.png" style="margin-right: 1em;">At the same time, we all know that “no join is faster than no join”. The inherent disadvantage of decomposing your data is the required assembly. If you are looking for “speed” or “scalability”, then denormalizing your data is usually the first step. The disadvantage? Now you have introduced a number of potential anomalies into your data: updates, inserts, and deletes can cause data inconsistencies unless you keep careful accounting of all duplication. One-to-One, and One-to-Many relations are usually easy to manage, but Many-to-Many in denormalized schemas are nothing but a recipe for disaster. That is, if you care about <a href="http://en.wikipedia.org/wiki/ACID#Consistency">consistency</a>.</p>
<p>Finally, since you lose the power of a general purpose query language (SQL), you are now at a mercy of the DSL provided by your new database. Mongo, Couch and many others had to introduce their own query language constructs alongside "map-reduce" functionality to address the problem of querying arbitrarily deep records. Now, I am a fan of both, but frankly, none I have worked with so far are as clean, or as easy to understand as SQL (<a href="http://rickosborne.org/download/SQL-to-MongoDB.pdf">case in point</a>) - with the downside of making me learn yet another query language.</p>
<h4><strong>Schema-free != Document Based</strong></h4>
<p>Document based and schema-free are often used interchangeably, but there is an important difference: schema-free does not necessarily imply nested data structures. Likewise, just because MySQL is “relational” does not mean that it must be fixed to a predefined schema - at create time, maybe, but not at runtime. Intersect the two statements, and it means that there is absolutely no reason why we cannot have a schema-free engine in MySQL:</p>
<p><a href="javascript:showme('7032_1');"> <b>> schema-free.sql</b></a>
<div style=" background:white;" id=7032_1>
<pre class="sql">mysql&gt; <span style="color: #993333; font-weight: bold;">USE</span> noschema;
mysql&gt; <span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> widgets;  <span style="color: #808080; font-style: italic;">/* look ma, no schema! */</span>
mysql&gt; <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> widgets <span style="color: #66cc66;">&#40;</span>id, name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;a&quot;</span>, <span style="color: #ff0000;">&quot;apple&quot;</span><span style="color: #66cc66;">&#41;</span>;
mysql&gt; <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> widgets <span style="color: #66cc66;">&#40;</span>id, name, type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;b&quot;</span>, <span style="color: #ff0000;">&quot;blackberry&quot;</span>, <span style="color: #ff0000;">&quot;phone&quot;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> widgets <span style="color: #993333; font-weight: bold;">WHERE</span> id = <span style="color: #ff0000;">&quot;a&quot;</span>;
+<span style="color: #808080; font-style: italic;">---------+---------------+</span>
| id      | name          |
+<span style="color: #808080; font-style: italic;">---------+---------------+</span>
| a       | apple         |
+<span style="color: #808080; font-style: italic;">---------+---------------+</span>
&nbsp;
mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> widgets;
+<span style="color: #808080; font-style: italic;">---------+---------------+--------+</span>
| id      | name          | type   |
+<span style="color: #808080; font-style: italic;">---------+---------------+--------+</span>
| a       | apple         | <span style="color: #993333; font-weight: bold;">NULL</span>   |
| b       | blackberry    | phone  |
+<span style="color: #808080; font-style: italic;">---------+---------------+--------+</span>
&nbsp;</pre>
</div>
<p>As long as we avoid nested data structures, then there is no reason why we should be limited by the columns defined in our tables because we can compose and decompose any relation at runtime. Not only would this mean no migrations or need to store null values, but you could also keep all the tools, drivers, and the SQL query language while adding the full flexibility of being schema-free. </p>
<h4><strong>Schema-free DB on top of MySQL</strong></h4>
<p>Not able to find any project that would give me this behavior, I ended up prototyping it myself over the weekend, and believe it or not, it works just fine. In fact, the output above is from a real console session with MySQL. All it took is an <a href="http://github.com/igrigorik/em-proxy">em-proxy server</a> with a little low-level protocol and query rewriting, and all of the sudden, my MySQL forgot that it requires a schema. Take it for a test-drive yourself (you will need Ruby 1.9):</p>
<blockquote><p>
git clone git://github.com/igrigorik/em-proxy.git && cd em-proxy<br />
ruby examples/schemaless-mysql/mysql_interceptor.rb<br />
<strong>mysql -h localhost -P 3307 --protocol=tcp</strong>
</p></blockquote>
<p><a href="javascript:showme('7032_2');"> <b>> schema-free-mysql.rb</b></a>
<div style=" background:white;" id=7032_2>
<pre class="ruby"><span style="color:#008000; font-style:italic;"># snip ... </span>
<span style="color:#008000; font-style:italic;"># build the select statements, hide the tables behind each attribute</span>
join = <span style="color:#996600;">&quot;select #{table}.id as id &quot;</span>
tables.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |column|
  join += <span style="color:#996600;">&quot; , #{table}_#{column}.value as #{column} &quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># add the joins to stich it all together</span>
join += <span style="color:#996600;">&quot; FROM #{table} &quot;</span>
tables.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |column|
  join += <span style="color:#996600;">&quot; LEFT OUTER JOIN #{table}_#{column} ON #{table}_#{column}.id = #{table}.id &quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
join += <span style="color:#996600;">&quot; WHERE #{table}.id = '#{key}' &quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> key
&nbsp;</pre>
</div>
<p><div class='download-link'>
							<a href='http://www.igvita.com/download.php?file=http://www.github.com/igrigorik/em-proxy/blob/master/examples/schemaless-mysql/mysql_interceptor.rb'><img alt='Download' class='leftalign' src='http://www.igvita.com/wp-content/plugins/dBeautifier/icons/downloads.png' /></a>
							<h4>
								<a href='http://www.igvita.com/download.php?file=http://www.github.com/igrigorik/em-proxy/blob/master/examples/schemaless-mysql/mysql_interceptor.rb'>mysql_interceptor.rb (MySQL Proxy in Ruby)</a>
							</h4><p>Downloads: 493 File Size: 0.0 KB </p>
						</div></p>
<p>Of course, this is nothing but a cute code example nor does it even cover all the different use cases, but let us look at the feature set: driver support for every language (you can point Rails + ActiveRecord, JDBC, etc.  at it out the box, no problem), tool support (GUI and command line), replication that works, basically impossible to corrupt, transactions, and so on. Not bad for half a day of hacking with a simple data model in the background:</p>
<p align="center"><img src="http://www.igvita.com/posts/10/attr-join.png"></p>
<p>Instead of defining columns on a table, each attribute has its own table (new tables are created on the fly), which means that we can add and remove attributes at will. In turn, performing a select simply means joining all of the tables on that individual key. To the client this is completely transparent, and while the proxy server does the actual work, this functionality could be easily extracted into a proper MySQL engine - I’m just surprised that no one has done so already. For a closer look, <a href="http://github.com/igrigorik/em-proxy/blob/master/examples/schemaless-mysql/mysql_interceptor.rb">check out the proxy code itself</a>, there are plenty of comments, which explain how it is all pieced together.</p>
<h4><strong>The gray zone of SQL vs NoSQL</strong></h4>
<p>So what is the point of all this? Well, I hope someone actually writes such an engine, because I believe there is a market for it. There is a lot to be said for a drop in, SQL compatible, schema-free engine, and unlike what the NoSQL propaganda may say, there is absolutely no reason why we can’t have many of the benefits of “NoSQL” within MySQL itself. There is no one clear winner for a database engine or model, so put some thought into your decision up front. Just because Mongo, TC, or Couch are 'document-oriented' or 'schema-free' does not mean they are necessarily better for your application. In the meantime, don't get me wrong, I am still rooting for all the NoSQL projects, as well as have high expectations for Drizzle - they are all doing fantastic work.</p>
<p class="download"><a href="http://pc.de/pages/schema-free-mysql-vs-nosql-be">Belorussian translation</a> kindly provided by Patricia Clausnitzer.</p>
<div class="feedflare">
<a href="http://feeds.igvita.com/~ff/igvita?a=syizv-mDxYU:knXSu-0VRkI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/igvita?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=syizv-mDxYU:knXSu-0VRkI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/igvita?i=syizv-mDxYU:knXSu-0VRkI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=syizv-mDxYU:knXSu-0VRkI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/igvita?i=syizv-mDxYU:knXSu-0VRkI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=syizv-mDxYU:knXSu-0VRkI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/igvita?i=syizv-mDxYU:knXSu-0VRkI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.igvita.com/~ff/igvita?a=syizv-mDxYU:knXSu-0VRkI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/igvita?i=syizv-mDxYU:knXSu-0VRkI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/igvita/~4/syizv-mDxYU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.igvita.com/2010/03/01/schema-free-mysql-vs-nosql/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.igvita.com/2010/03/01/schema-free-mysql-vs-nosql/</feedburner:origLink></item>
	</channel>
</rss>
