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

<channel>
	<title>RabbitMQ</title>
	<atom:link href="http://www.rabbitmq.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rabbitmq.com/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 21 Feb 2012 12:58:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>AtomizeJS: Distributed Software Transactional Memory</title>
		<link>http://www.rabbitmq.com/blog/2012/02/21/atomizejs-distributed-software-transactional-memory/</link>
		<comments>http://www.rabbitmq.com/blog/2012/02/21/atomizejs-distributed-software-transactional-memory/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 12:55:18 +0000</pubDate>
		<dc:creator>Matthew Sackman</dc:creator>
				<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[web messaging]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=176</guid>
		<description><![CDATA[AtomizeJS is a JavaScript library for writing distributed programs, that run in the browser, without having to write any application specific logic on the server. Here at RabbitMQ HQ we spend quite a lot of time arguing. Occasionally, it's about important things, like what messaging really means, and the range of different APIs that can [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a href="http://atomizejs.github.com/">AtomizeJS</a> is a JavaScript library for writing distributed programs, that run in the browser, without having to write any application specific logic on the server.</strong></p>

<p>Here at RabbitMQ HQ we spend quite a lot of time arguing. Occasionally, it's about important things, like what <em>messaging</em> really means, and the range of different APIs that can be used to achieve <em>messaging</em>. RabbitMQ and AMQP present a very explicit interface to messaging: you very much have verbs <em>send</em> and <em>receive</em> and you need to think about what your messaging patterns are. There's a lot (of often quite clever stuff) going on under the bonnet but nevertheless, the interface is quite low-level and explicit, which gives a good degree of flexibility. Sometimes though, that style of API is not the most natural fit for the problem you're trying to solve - do you really reach an impasse and think "What I need here is an AMQP-message broker", or do you, from pre-existing knowledge, realise that you could choose to use an AMQP-message broker to solve your current problem?</p>

<p><a href="http://atomizejs.github.com/getting_started.html">AtomizeJS</a> exists at the opposite end of the spectrum. There is lots of messaging involved, but you almost never get to see any of it. Instead, you write transactions in JavaScript that modify objects, and those objects are shared between all clients that are connected to the same AtomizeJS server. The <a href="http://atomizejs.github.com/api.html">API</a> that you're given lets you do slightly more powerful things than you're used to from database transactions, in particular, <code>retry</code> allows you to abort a transaction but then restart it automatically once someone else has changed one of the variables you read. This means you have the observer-pattern, and from that you can then build any explicit messaging patterns you want. In most cases, I doubt you'll be building APIs that say <em>send</em> or <em>receive</em>, instead you'll be building richer data-structures - work queues, shared dictionaries etc. The question to pose then is: is it easier to build these things based on top of a transaction-like API such as offered by AtomizeJS, or on top of an explicit messaging API such as offered by RabbitMQ and AMQP brokers. There is no one solution and horses-for-courses etc, but please leave your thoughts below.</p>

<p>The gain that AtomizeJS provides is not so much in the use of STM from the browser, but the use of STM against a distributed object. This allows you to trivially share state between browsers, modify it safely in intuitive terms, and thus build your applications with little or no application-specific server-side code. Currently, it's a little clunky to use with browsers that don't support bleeding-edge JavaScript features (though I've provided some tooling to try and mitigate this), and everything does work with the latest versions of Chrome, Firefox, IE, Safari, and Opera. Please <a href="http://atomizejs.github.com/getting_started.html">have a go</a> and <a href="http://atomizejs.github.com/contact.html">let us know</a> what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/02/21/atomizejs-distributed-software-transactional-memory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SockJS 0.2 released!</title>
		<link>http://www.rabbitmq.com/blog/2012/01/24/sockjs-0-2-released/</link>
		<comments>http://www.rabbitmq.com/blog/2012/01/24/sockjs-0-2-released/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 17:16:07 +0000</pubDate>
		<dc:creator>Marek Majkowski</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=164</guid>
		<description><![CDATA[SockJS version 0.2 has been released: https://groups.google.com/group/sockjs/browse_thread/thread/79893c8545c49f06 You can test it in the usual playground: http://sockjs.popcnt.org/example-cursors.html http://sockjs.cloudfoundry.com/tests-qunit.html Apart from ton of general updates and few API tweaks, SockJS 0.2 contains two major features: Faster connection times - due to a better fallback-detection algorithm. Raw websocket api - should make it easier to write command line [...]]]></description>
			<content:encoded><![CDATA[<p><center>
<a href="http://www.rabbitmq.com/wp-uploads/2012/01/sockjs-logo.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/01/sockjs-logo-150x150.png" alt="" title="sockjs-logo" width="150" height="150" class="alignnone size-medium wp-image-167" /></a>
</center></p>

<p>SockJS version 0.2 has been released:</p>

<ul>
<li><a href="https://groups.google.com/group/sockjs/browse_thread/thread/79893c8545c49f06">https://groups.google.com/group/sockjs/browse_thread/thread/79893c8545c49f06</a></li>
</ul>

<p>You can test it in the usual playground:</p>

<ul>
<li><a href="http://sockjs.popcnt.org/example-cursors.html">http://sockjs.popcnt.org/example-cursors.html</a></li>
<li><a href="http://sockjs.cloudfoundry.com/tests-qunit.html">http://sockjs.cloudfoundry.com/tests-qunit.html</a></li>
</ul>

<p><span id="more-164"></span></p>

<p>Apart from ton of general updates and few API tweaks, SockJS 0.2
contains two major features:</p>

<ul>
<li>Faster connection times - due to a better fallback-detection algorithm.</li>
<li>Raw websocket api - should make it easier to write
   command line clients for SockJS.</li>
</ul>

<p>That means two out of three updates to SockJS protocol <a href="https://groups.google.com/group/sockjs/browse_thread/thread/cd2b468d312bd5e1">I proposed
about a month ago are done</a>. The last major feature remaining is
binary data support.</p>

<p>Unfortunately <a href="https://groups.google.com/group/sockjs/browse_thread/thread/4b0f3d426223ac0d">the releases rarely go smoothly</a>, but thanks to
alert SockJS users the problem was quickly spotted and fixed.</p>

<p>So, happy playing with <a href="http://sockjs.org">SockJS</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/01/24/sockjs-0-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RabbitMQ 2.7.0 and 2.7.1 are released</title>
		<link>http://www.rabbitmq.com/blog/2011/12/20/rabbitmq-2-7-0-and-2-7-1-are-released/</link>
		<comments>http://www.rabbitmq.com/blog/2011/12/20/rabbitmq-2-7-0-and-2-7-1-are-released/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 17:43:55 +0000</pubDate>
		<dc:creator>Zteve</dc:creator>
				<category><![CDATA[New Features]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=140</guid>
		<description><![CDATA[The previous release of RabbitMQ (2.7.0) brought with it a better way of managing plugins, one-stop URI connecting by clients, thread-safe consumers in the Java client, and a number of performance improvements and bug-fixes. The latest release (2.7.1) is essentially a bug-fix release; though it also makes RabbitMQ compatible with Erlang R15B and enhances some [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-November/016069.html">previous release of RabbitMQ</a> (2.7.0) brought with it a better way of managing plugins, one-stop URI connecting by clients, thread-safe consumers in the Java client, and a number of performance improvements and bug-fixes. The <a href="http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-December/016941.html">latest release</a> (2.7.1) is essentially a bug-fix release; though it also makes RabbitMQ compatible with Erlang R15B and enhances some of the management interface. The previous release didn't get a blog post, so I've combined both releases in this one.  (These are my own personal remarks and are NOT binding; errors of commission or omission are entirely my own -- Steve Powell.)<span id="more-140"></span></p>

<h3>plugins</h3>

<p>Prior to 2.7.0 if you wanted to use a plugin then a <tt>.ez</tt> file was placed in the <tt>plugins</tt> directory, and the broker restarted. Any plugin found in this directory was installed on startup.  This meant two things: plugins weren't supplied with the server (even our supported ones), and installing or uninstalling a plugin involved moving files about <em>and</em> ensuring other plugin dependencies were installed. Administration of plugins was unnecessarily messy.</p>

<p>In 2.7.0, we introduced a command <tt>rabbitmq-plugins</tt>, to enable or disable any plugin in the <tt>plugins</tt> directory. Simply issue the command <tt>rabbitmq-plugins list</tt> to see what plugin files are there, and <tt>rabbitmq-plugins enable &lt;plugin-name&gt;</tt> to use one the next time the broker starts. No files need to be moved around -- they can stay in the plugins directory all the time -- and all the rabbit plugins are now supplied with the server, disabled by default.  The command also understands which plugins depend upon which others, and enables dependencies automatically. Using and managing plugins is now much easier. See <a href="http://www.rabbitmq.com/plugins.html">the plugins page</a> for more.</p>

<p>In 2.7.1 there is a fix to the <tt>consistent-hash-exchange</tt> plugin which mis-routed messages when handling multiple exchanges.</p>

<h3>connect by URI</h3>

<p>All of the rabbit clients (.NET, Java and Erlang) clients accept an <tt><strong>amqp</strong></tt> URI scheme for connections. This is a convenient <em>one-stop shop</em> allowing the username and password, hostname and port, and virtual host, to be supplied by a single URI or String parameter. For example:</p>

<blockquote>
<pre><strong>amqp://guest:ghost@rabbit01.coderus.moc:5672/vhost01</strong></pre>
</blockquote>

<p>See the individual client APIs for details.</p>

<h3>Java threads</h3>

<p>In Release 2.7.0 the threading structure of the Java client has been significantly redesigned. Before this release there were restrictions in what could be done in the Java client's <code>Consumer</code> callback methods, and also on which application threads can call <code>Channel</code> methods. These have been due to the underlying threading structure of the Java client which shared the channel thread with the callbacks. Locks on the channel and connection objects meant that calling <code>Channel</code> methods directly from the <code>Consumer</code> resulted in deadlocks (with a few exceptions, like acknowledgements). The <code>QueueingConsumer</code> helper class was made available to isolate applications from some of these issues, at the cost of introducing another queue (in the Java client).</p>

<p>With the new threading structure, there are far fewer restrictions upon which application threads can call channel operations, because all <code>Consumer</code> callbacks are executed on threads which are separate from the channel. In fact, it is now possible to configure the connection to manage a pool of threads used specifically for callbacks — preserving the order of execution of these within each channel. Simple client applications can take the default which provides a small pool of callback threads and sophisticated clients can provide their own <code>ExecutorService</code> object, which allows them to create and manage the size and behaviour of the thread pool themselves. <code>QueueingConsumer</code> is now no longer necessary, for everything one would want to do as a result of a <code>Consumer</code> callback can be done in the <code>Consumer</code> method directly, without deadlocks.  See the <a href="http://www.rabbitmq.com/api-guide.html">Java API Guide</a> for more.</p>

<p>2.7.1 fixed a few irritations in the Java Client adjustments in 2.7.0: we inadvertently hid some of the API, and this has now been restored. There were also some potential resource leaks which we have now fixed.</p>

<h3>performance</h3>

<p>A number of small performance improvements have been made to the server in both 2.7.0 and 2.7.1. These have been quite varied in scope, and I can only touch on some of them here.</p>

<ul>
    <li>In the first place, basic file I/O has been improved by the simple expedient of using lower-level basic file operations. This has allowed certain operations to occur in parallel that were previously serialised through an Erlang process. This results in removing some bottlenecks, and slightly speeds up several areas, including server shutdown.</li>
    <li>An area of intense I/O, interestingly unaffected by the tweak above, is what is known as the 'message store'. This is, unsurprisingly, where messages are stored (stored for various reasons, not only message persistence). Rather than using a conventional database, RabbitMQ manages its own file storage for messages.  (A conventional database has almost the entirely wrong performance profile for queueing -- the most recently used items are likely to be the ones accessed last.)  The messages store is one of the most sophisticated parts of the server because it needs to respond very quickly without gating the rest of the system by the relatively slow I/O operations it performs. It behaves something like a paging system cache, in that while messages are waiting to be written they can potentially be 'stolen' from the write list if they are subsequently read, rewritten or even deleted. The 'overtaking' rules are quite different from those of a paging system, however, and in this release, the organisation was changed to allow some deletes to 'cancel' store requests which hadn't yet occurred. This results in reducing unnecessary writes and therefore higher overall throughput for every queue. Extensive tests have shown an improvement in performance with preserved reliability, even under load.</li>
    <li>There was sub-optimal treatment of a connection with a large number of consumers, especially if they were of low utilisation. There appeared to be an overhead for consumers that were relatively inactive. In 2.7.0 this has been improved, which means that having lots of low-use consumers has far less of an impact on overall performance.</li>
    <li>Deletion of queues with a large number of bindings and exchanges with a large number of bindings took rather longer than we would have liked. This has been speeded up in 2.7.1.</li>
</ul>

<h3>HiPE option</h3>

<p>Erlang offers a High Performance compiler (HiPE) for some platforms whereby Erlang modules can be compiled to native code. This compilation does not always produce a faster system, however, and is not supported by all Erlang environments and versions. In 2.7.0 we introduced a <a href="http://www.rabbitmq.com/configure.html">configuration option</a> to use HiPE, and a re-compilation is performed automatically at server startup. Not every rabbit module is re-compiled — only those that we have determined may benefit from this treatment. Although this option delays startup by some tens of seconds, it produces significant performance improvements at runtime which may be crucial for some larger rabbit installations.</p>

<p>This option is <em>disabled</em> by default, since it may actually affect behaviour (not that we have detected this), and the performance improvements are not tested on all the environments our users employ. However, if it works for you, go for it. If your Erlang environment does not support HiPE, there is a brief diagnostic message and the option is ignored.</p>

<p>We would be very interested in your experiences with this feature.</p>

<h3>re-queued messages</h3>

<p>RabbitMQ deals with FIFO queues. If all goes well, the order the messages are put on a queue is the same as the order they are consumed. When a consumer fails, however, some of the messages it received may not have been acknowledged, and in this case these messages are re-queued so that they may be delivered again. In this way messages may appear to be re-ordered. Before this release, there was no guarantee of the order of re-queued messages.</p>

<p>From 2.7.0 the relative order <em>of re-queued messages from a single consumer</em> is preserved. Therefore, if another consumer receives them later, they will be consumed in the same order they originally appeared. Of course, if two or more consumers on the same queue fail, there is no guarantee that messages re-queued by <em>distinct</em> consumers will retain their relative order. But in the majority of cases where order matters, this guarantee should be enough.</p>

<h3>high availability problems</h3>

<p>A number of fixes for high availability features (mostly introduced in 2.7.0) were included in 2.7.1. These relate to some memory leaks; recovery of master queues; frequent restarting causing HA queues to fail; and promotion of slaves (to master) failing under some circumstances.  The general quality of this code area is high, but the complex nature of the failure scenarios (which this feature is specifically designed to protect against) makes it a fruitful one for bugs to lurk. Nearly all the bugs fixed in 2.7.1 are due to rare or obscure combinations of recovery or restart events, and we confidently expect there to be few surprises left. Of course, High Availability doesn't mean Guaranteed Availability, so there are going to be situations from which we cannot recover.</p>

<h3>other small improvements and bug fixes</h3>

<ul>
    <li>If you ran a broker for a very long time it was possible to wrap one of the internal GUIDs (Globally Unique IDentifiers). Clearly this was not intended, and in any case it can't cause a problem in practice can it?  Well it did!  (Wouldn't you know it -- some people run brokers for a very long time!) We've fixed it in 2.7.1.</li>
    <li>The management plugin interface now displays a bit more information about queue lengths and shovel information is presented a little more nicely, plus there were a number of small problems with statistics and HA slave information that are now fixed.</li>
    <li><tt>rabbitmqctl eval &lt;expr&gt;</tt> is new (in 2.7.1) to evaluate an arbitrary Erlang expression in the broker node.</li>
    <li>.net client session autoclose could sometimes return an AlreadyClosed exception (it is supposed not to do this).</li>
    <li>The STOMP adapter didn't support reply-to queues properly (they weren't re-usable), and could supply multiple message-id headers on a MESSAGE frame if the SEND frame supplied one. We now check for this latter condition and reject the SEND.</li>
    <li>Some functions used which are no longer in Erlang R15B have been removed (and the code rewritten), so that RabbitMQ should now build and run under the latest Erlang Release. Let us know if not!</li>
</ul>

<h2>thank you for listening</h2>

<p>As usual, the rabbit team welcome feedback of your experiences, good or bad. We encourage you to use the <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss">rabbitmq-discuss</a> mailing list.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/12/20/rabbitmq-2-7-0-and-2-7-1-are-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ponies, Dragons and Socks</title>
		<link>http://www.rabbitmq.com/blog/2011/11/03/ponies-dragons-and-socks/</link>
		<comments>http://www.rabbitmq.com/blog/2011/11/03/ponies-dragons-and-socks/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 13:06:34 +0000</pubDate>
		<dc:creator>Marek Majkowski</dc:creator>
				<category><![CDATA[web messaging]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=125</guid>
		<description><![CDATA[We were wondering how to present SockJS and its possibilities to a wider audience. Having a working demo is worth much more than explaining dry theory, but what can you present if you are just a boring technologist, with no design skills whatsoever? With questions like that it's always good to open a history book [...]]]></description>
			<content:encoded><![CDATA[<p>We were wondering how to present SockJS and its possibilities to a
wider audience. Having a working demo is worth much more than
explaining
<a href="http://www.rabbitmq.com/blog/2011/09/13/sockjs-websocket-emulation/">dry theory</a>,
but what can you present if you are just a boring technologist, with
no design skills whatsoever?</p>

<p>With questions like that it's always good to open a history book
and review previous generation of computer geeks with no artistic
skills. What were they doing? On consoles with green letters
they were playing geeky computer games,
<a href="http://en.wikipedia.org/wiki/MUD">MUDs (Multi User Dungeons)</a> were
especially popular.</p>

<p>Hey, we can do that!</p>

<p><span id="more-125"></span></p>

<p><center><img alt="mud" src="/wp-uploads/2011/11/squirrel_tales.png" /></center></p>

<p>So here it is, a rough and dirty, hacked together in an afternoon MUD!
But it aint a normal MUD, it's a unique one:</p>

<ul>
<li>The world isn't exactly large, with five locations and 6 commands
   in total.</li>
<li>But it's an in-browser game, using <a href="http://sockjs.org">SockJS</a> underneath.</li>
<li>It's built using Django, and the state is handled using Django ORM.</li>
</ul>

<p>So, forget the 21st century and dive into an ancient world of dragons,
at least for a few minutes:</p>

<ul>
<li><a href="http://mud.sockjs.org">http://mud.sockjs.org</a></li>
</ul>

<p>If you're interested in technology feel free
<a href="https://github.com/sockjs/sockjs-mud">to take a look at the sources</a>. Also,
as the project is using Django ORM you can add new locations using
<a href="http://mud.sockjs.org/admin">Django Admin</a> (user: guest, pass:
guest). Unleash your creativity! Unfortunately there isn't a simple
way of restricting Django Admin users, so you can't see what you
added. You may also want to take a look at the
<a href="https://github.com/sockjs/sockjs-mud/blob/master/mud/initial_data.json">initial database fixture</a>.</p>

<p>Here's a diagram illustrating the architecture of this demo:</p>

<p><center><img alt="MUD architecture" src="/wp-uploads/2011/11/sockjs-mud-architecture.png" width="240px" /></center></p>

<p>As you can see it's quite simple, and it follows one of the
recommended SockJS deployment models. It should be possible to
scale it horizontally, although this game is only a toy and we haven't
really tested that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/11/03/ponies-dragons-and-socks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performance of Queues: when less is more</title>
		<link>http://www.rabbitmq.com/blog/2011/10/27/performance-of-queues-when-less-is-more/</link>
		<comments>http://www.rabbitmq.com/blog/2011/10/27/performance-of-queues-when-less-is-more/#comments</comments>
		<pubDate>Thu, 27 Oct 2011 16:45:24 +0000</pubDate>
		<dc:creator>Matthew Sackman</dc:creator>
				<category><![CDATA[New Features]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[queues]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=108</guid>
		<description><![CDATA[Since the new persister arrived in RabbitMQ 2.0.0 (yes, it's not so new anymore), Rabbit has had a relatively good story to tell about coping with queues that grow and grow and grow and reach sizes that preclude them from being able to be held in RAM. Rabbit starts writing out messages to disk fairly [...]]]></description>
			<content:encoded><![CDATA[<p>Since the <em>new persister</em> arrived in RabbitMQ 2.0.0 (yes, it's not so
<em>new</em> anymore), Rabbit has had a relatively good story to tell about
coping with queues that grow and grow and grow and reach sizes that
preclude them from being able to be held in RAM. Rabbit starts writing
out messages to disk fairly early on, and continues to do so at a
gentle rate so that by the time RAM gets really tight, we've done most
of the hard work already and thus avoid sudden bursts of
writes. Provided your message rates aren't too high or too bursty,
this should all happen without any real impact on any connected
clients.</p>

<p>Some recent discussion with a client made us return to what we'd
thought was a fairly solved problem and has prompted us to make some
changes.<span id="more-108"></span> First, we
<a href="http://www.rabbitmq.com/blog/2011/09/24/sizing-your-rabbits/">took some time to understand better how CPU use per message varies as queues get longer and go to disk</a>,
and what the effect of that is. The conclusions are not necessarily
obvious. Then we started thinking about the justifications behind some
of the decisions queues take in the process of going from a
purely-in-RAM queue to a purely-on-disk queue.</p>

<p>An AMQP queue in Rabbit is not simple functional FIFO queue. There are
in fact at least four "queues" used internally by each AMQP queue,
each of which are allowed to hold messages in various different
states. These states are things like: Is the message held in RAM
(regardless of whether it has <em>additionally</em> been written to disk)?;
Is the message itself on disk, but its location within the queue still
only held in RAM? That sort of thing. Each message in the AMQP queue
will only appear at any one time in one of these internal queues, but
they can move from queue to queue if and when their state changes
(though the movement between these internal queues respects the
overall order of messages within the AMQP queue). There is then a
fifth "queue" which is not really a queue at all. It is more a couple
of numbers that indicate the range of messages that are held solely on
disk (if you like, these are pointers to the head and tail of the
"queue" which is solely on disk). Messages in this form have, in
theory, zero RAM-cost (depending on how you count (numbers cost RAM
too you know!), and elsewhere in Rabbit you can be fairly sure the
best you can get down to is a few bytes per message). The full gory
details can be gleaned from the essay at the top of the
<a href="http://hg.rabbitmq.com/rabbitmq-server/file/default/src/rabbit_variable_queue.erl">variable_queue</a>
module. It's not really that terrifying, but it isn't exactly noddy
stuff either. The tricky bits are working out how you decide which
messages should be in which states, and when, and I'm not going to
cover those decisions in this post.</p>

<p>A message that is captured by this fifth "queue" will potentially take
two reads to go from that purely-on-disk form right back to a
fully-in-RAM message. This is because every message has a message ID
(which is random, unordered, and allocated to each message before it
arrives at any queue, so is useless for determining relative position
within an AMQP queue), and within each AMQP queue each message is known by its
per-queue sequence ID, which enforces the relative order of messages
within an AMQP queue. This fifth "queue" can be thought of as a
mapping from sequence ID to message ID (plus some
per-message-per-queue state), and then you can use a different
subsystem to transform that message ID to the actual message.</p>

<p>As a result of these two reads (though the way we structure it, one of
the reads is shared between 16k messages, so it's probably closer to
1+(1/16384) reads per message, at least by default), we've previously
tried to prevent the use of this fifth "queue": in the past, even when
memory is running very low, we'll write messages out to disk fully,
but then still hold onto a record in RAM (though by this point it's a
fairly small record per message), assuming that this will give us an
advantage later on: yes, it costs more RAM, but if some other big AMQP
queue suddenly gets deleted and frees up lots of RAM then by holding
onto this smallish record per message, we avoid having to do the two
reads to go from the fifth "queue" back to a full message, and will
only have to do a single read instead. Only when RAM runs out
completely will we suddenly dump (almost) everything into this fifth
"queue" (though by this point, everything will be on disk by now
anyway so it's more or less a no-op -- we're just freeing up RAM in
this transition).</p>

<p>However, because of the effective amortisation of at least one of
these reads, using the fifth "queue" isn't as expensive as we
feared. Plus, if you start to use it earlier then the queue grows in
RAM at a slower rate: messages have the lowest per-message RAM cost when
they're in this fifth "queue", and thus the greater your use of this
"queue", the lower the rate at which your queue will consume RAM. This
on its own helps Rabbit smooth out the transition to purely on disk
operation (given the same growth rate in messages, a lower growth rate in RAM will result in a lower rate of disk ops).</p>

<p>So we've changed the behaviour of Rabbit's AMQP queues to use this
fifth "queue" more eagerly. Benchmarks suggest that this seems to
result in an AMQP queue's memory use flat-lining earlier on in its
growth, and actually seems to make Rabbit able to deliver messages
from large AMQP queues out to consumers faster (probably because by
limiting the size of the other four internal queues, some operations
which were found to be very inefficient (such as joining two
functional queues together (Erlang's default queue module does a plain
append (<code>++</code>) here, which is expensive)) are avoided, thus more CPU is
available for driving consumers). The downside is that queues now
spend more time doing reads, but that seems to have been more than
offset by the lower user jiffies per message.</p>

<p>Below is a graph. This is very exciting -- not just because of the
fact that most of my blog posts are endless words. It shows three runs
of the same test program. This test program does the following:</p>

<ol>
<li>It creates 3 queues.</li>
<li>It binds those 3 queues to a fanout exchange.</li>
<li>It then starts publishing 200-byte messages to that exchange at 600
messages / second.</li>
<li>For the first 120 seconds, it has 20 consumers per queue consuming
without auto-ack, one ack per message, and a QoS pre-fetch of 1. This is known to be a very expensive way of consuming
messages. Further, the ack is deliberately delayed so that,
ignoring network latency, the maximum aggregate consuming rate will
be 1200 messages / second.</li>
<li>After 120 seconds, the consumers are stopped, and not started again
until there is a total backlog of 500,000 messages (i.e. each of
the 3 queues will have around 166,000 messages).</li>
<li>After that, the consumers resume as before, and you hope that the
queues can cope with the continuing publishes and drive their
backlog out to the consumers. Hopefully, all the queues will
eventually become empty again.</li>
</ol>

<p>Now depending on your CPU, RAM, network latency, and <em>high_watermark</em>
settings, this backlog can be purely in RAM only, and so no disk
operations ever take place; or it could be purely on disk; or anywhere
in between. Our desktops in the office here tend to be too powerful
for this test to cause any problems (the backlog always drains), but
on some EC2 hosts, with older versions of Erlang and older versions of
Rabbit, it was possible to reach a point where this backlog would
never drain, and instead grow.</p>

<p>In the following graph, we have three successful runs of this test,
both on <em>m1.large</em> EC2 instances, with the test being run on a
separate EC2 instance (i.e. we really were going across the
network). These are running Ubuntu images, but with a locally compiled
Erlang R14B04 installation. The three runs are: 1) what was on our
default branch prior to this work being merged; 2) our default branch
after this work was merged; 3) the 2.6.1 release.</p>

<p><a href="http://www.rabbitmq.com/wp-uploads/2011/10/graph.svg">
<embed type="image/svg+xml" src="http://www.rabbitmq.com/wp-uploads/2011/10/graph.svg" width="800" height="600"/>
</a></p>

<p>Since 2.6.1 was released, a fairly large number of performance tweaks
have been made, and this is shown by the faster rate at which the
backlog disappears. But the "default prior to change" and "2.6.1"
memory usages are fairly similar, whereas, on average, the "default
post change" has a lower memory usage. The memory measurements are not
especially compelling however as, owing to Erlang being an
auto-garbage-collected language, it is not always the case that
improving memory efficiency internally results in the VM requesting
less RAM or returning RAM to the OS faster. What is more compelling is
the faster rate at which the backlog is eliminated and the lower
cumulative jiffies: even though "default post change" is doing more
messages per second than either of the other runs, it still uses fewer
jiffies per second than the other runs.</p>

<p>Hopefully this change will make improvements to many users across many
scenarios. It's possible there may be some use cases where it performs
worse -- we certainly can't rule that out. No problem in software
engineering that's worth solving has a single correct solution. This
case shows that sometimes, using less memory and doing apparently more disk ops
can actually make things go faster overall.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/10/27/performance-of-queues-when-less-is-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>High Availability in RabbitMQ: solving part of the puzzle</title>
		<link>http://www.rabbitmq.com/blog/2011/10/25/high-availability-in-rabbitmq-solving-part-of-the-puzzle/</link>
		<comments>http://www.rabbitmq.com/blog/2011/10/25/high-availability-in-rabbitmq-solving-part-of-the-puzzle/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 15:52:02 +0000</pubDate>
		<dc:creator>Matthew Sackman</dc:creator>
				<category><![CDATA[New Features]]></category>
		<category><![CDATA[broker]]></category>
		<category><![CDATA[high availability]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=103</guid>
		<description><![CDATA[﻿﻿In RabbitMQ 2.6.0 we introduced Highly Available queues. These necessitated a new extension to AMQP, and a fair amount of documentation, but to date, little has been written on how they work. High Availability (HA) is a typically over-used term and means different things to different people. In the context of RabbitMQ, there are a [...]]]></description>
			<content:encoded><![CDATA[<p>﻿﻿In
<a href="http://www.rabbitmq.com/news.html#2011-08-31T16:15:42+0100">RabbitMQ 2.6.0</a>
we introduced <a href="http://rabbitmq.com/ha.html">Highly Available</a>
queues. These necessitated a
<a href="http://www.rabbitmq.com/extensions.html#consumer-cancel-notify">new extension</a>
to AMQP, and a fair amount of
<a href="http://rabbitmq.com/ha.html">documentation</a>, but to date, little has
been written on how they work.<span id="more-103"></span></p>

<p><em>High Availability</em> (HA) is a typically over-used term and means
different things to different people. In the context of RabbitMQ,
there are a number of aspects of <em>high availability</em>, some of which
this work does solve and some of which it does not. The things it does
not solve include:</p>

<ol>
<li><p>Maintaining connections to a RabbitMQ broker or node: using some
sort of TCP load-balancer or proxy is the best route here, though other
solutions such as dynamically updating DNS entries or just pre-loading
your clients with a list of addresses to connect to may work just as
well.</p></li>
<li><p>Recovery from failure: in the event that a client is disconnected
from the broker owing to failure of the node to which the client was
connected, if the client was a publishing client, it's possible for
the broker to have accepted and passed on messages from the client
without the client having received confirmation for them; and likewise
on the consuming side it's possible for the client to have issued
acknowledgements for messages and have no idea whether or not those
acknowledgements made it to the broker and were processed before the
failure occurred. In short, you still need to make sure your consuming
clients can identify and deal with duplicate messages.</p></li>
<li><p>Auto-healing from network partitions or splits. RabbitMQ makes use
of the Erlang distributed database Mnesia. This database itself does
not cope with network partitions: it very much chooses <em>Consistency</em>
and <em>Availability</em> and not <em>Partitions</em> from the <em>CAP</em> triangle. As
RabbitMQ depends on Mnesia, RabbitMQ itself has the same
properties. Thus the HA work in RabbitMQ can prevent queues from
disappearing in the event of a node failure, but does not have
anything to say about automatically rejoining the failed node when it
is repaired: this still requires manual intervention.</p></li>
</ol>

<p>These are not new problems at all; and RabbitMQ's HA work does not
attempt to address these problems. Instead, it focuses solely on
preventing queues from being bound to a single node in a cluster.</p>

<p>The previous situation was that a queue exists only on one node. If
that node fails, the queue becomes unavailable. The HA work solves
this by mirroring a queue on other nodes: all actions that occur on
the queue's master are intercepted and applied in the same order to
each of the slaves within the mirror.</p>

<p>This requires:</p>

<ol>
<li><p>The ability to intercept all actions being performed on a
queue. Fortunately, the code abstractions we already have makes this
fairly easy.</p></li>
<li><p>The ability for those actions to be communicated reliably,
consistently and in order to all the slaves within the mirror. For
this we have written a new
<a href="http://hg.rabbitmq.com/rabbitmq-server/file/default/src/gm.erl">guaranteed multicast</a>
module (also known as atomic broadcast).</p></li>
<li><p>The ability to reliably detect the loss of a node in such a way
that no messages sent from that node reach a subset of the slaves: to
ensure the members of the mirrored queue stay in sync with each other,
it's crucial that in the event of the failure of the master, any
messages that the master was in the process of sending to the slaves
either fail completely or succeed completely (this is really the
<em>atomic</em> in <em>atomic broadcast</em>).</p></li>
</ol>

<p>In addition, all this communication between the members of the mirror
occurs in an asynchronous fashion. This has advantages such as it
prevents the master from being slowed down if one of the slaves starts
struggling; but it also has disadvantages such as the complexity of
interleavings of actions in the event of failure of the master and
promotion of a slave.</p>

<p>Once the master does fail, a slave is chosen for promotion. The slave
chosen is the eldest slave, in the belief that it's the most likely to
have contents that match the contents of the failed master queue. This
is important because currently there is no eager synchronisation of
mirrored queues. Thus if you create a mirrored queue, send messages
into it, and then add another node which then mirrors that queue, the
slave on the new node will not receive the existing messages. Only new
messages published to the queue will be sent to all current members of
the mirrored queue. Thus by consuming from the queue and thus
processing the messages at the head of the queue, the
non-fully-mirrored messages will be eliminated. Consequently, by
promoting the eldest slave, you minimise the number of messages at the
head of the queue that may have only been known to the failed master.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/10/25/high-availability-in-rabbitmq-solving-part-of-the-puzzle/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Keeping It Realtime Conference (Portland, OR)</title>
		<link>http://www.rabbitmq.com/blog/2011/10/19/keeping-it-realtime-conference-portland-or/</link>
		<comments>http://www.rabbitmq.com/blog/2011/10/19/keeping-it-realtime-conference-portland-or/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 13:51:22 +0000</pubDate>
		<dc:creator>Marek Majkowski</dc:creator>
				<category><![CDATA[Talks and conferences]]></category>
		<category><![CDATA[web messaging]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=100</guid>
		<description><![CDATA[There's a lot of hot stuff happening in the web technology lately. JavaScript seems to be bearing the torch, both browser-side and server-side. At the RabbitMQ HQ we're interested in developments in the wide world of messaging, and we're particularly excited about the JavaScript angle on messaging - namely WebSockets and related technologies. The good [...]]]></description>
			<content:encoded><![CDATA[<p>There's a lot of hot stuff happening in the web technology lately.
JavaScript seems to be bearing the torch, both
browser-side and server-side.</p>

<p>At the RabbitMQ HQ we're interested in developments in the wide world of
messaging, and we're particularly excited about the JavaScript angle on
messaging - namely WebSockets and related technologies.</p>

<p><span id="more-100"></span></p>

<p><center><img alt="Krt " src="/wp-uploads/2011/10/krt.png" /></center></p>

<p>The good news is - there will be a conference dedicated to these topics:</p>

<ul>
<li><a href="http://krtconf.com/">Keeping It Realtime Conference</a></li>
</ul>

<p>The conference will take two days on Nov 7 and 8 in Portland, OR.</p>

<p>I'm delighted to announce that I'll be giving a talk there. I'll speak
about our view on messaging in the web environment, our attempt (and
failure) to build a generic web-messaging service, and finally I'll
describe what we came up after all this - the <a href="http://sockjs.org">SockJS project</a>. (Which is a simple WebSocket emulation layer, but it took us a while to understand why this is the best approach to do web-messaging.)</p>

<p>I'll be hanging around there for the two days - feel free to talk to me
about SockJS, RabbitMQ, AMQP or just messaging in general in any flavour.</p>

<p>See you in Portland!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/10/19/keeping-it-realtime-conference-portland-or/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PubSubHuddle &#8220;Realtime Web&#8221; talk</title>
		<link>http://www.rabbitmq.com/blog/2011/09/26/pubsubhuddle-realtime-web-talk/</link>
		<comments>http://www.rabbitmq.com/blog/2011/09/26/pubsubhuddle-realtime-web-talk/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 16:23:58 +0000</pubDate>
		<dc:creator>Marek Majkowski</dc:creator>
				<category><![CDATA[Talks and conferences]]></category>
		<category><![CDATA[web messaging]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=98</guid>
		<description><![CDATA[I was asked to do a short presentation during the PubSubHuddle meetup. The talk was about current development of WebSockets, its issues and building web applications using them. In the presentation I present the evolution of simple shared-nothing architecture and I try to explain why, in order to use web messaging, the website architecture should [...]]]></description>
			<content:encoded><![CDATA[<p>I was asked to do a short presentation during the
<a href="http://www.pubsubhuddle.com/">PubSubHuddle meetup</a>. The talk was
about current development of WebSockets, its issues and building web
applications using them.</p>

<p><center>
<img alt="Sock" src="/wp-uploads/2011/09/huddle4.png" />
</center></p>

<p><span id="more-98"></span></p>

<p>In the presentation I present the evolution of simple shared-nothing architecture and I
try to explain why, in order to use web messaging, the website
architecture should be truly asynchronous on every stage.</p>

<p>All that is an attempt to express a rationale for the
<a href="https://github.com/sockjs/sockjs-client">SockJS project</a>.  Actually,
the full story behind SockJS is much deeper, but probably nobody cares
about every detail, I am guessing.</p>

<p>The presentation is available here:</p>

<ul>
<li><a href="https://github.com/sockjs/sockjs-client/wiki/pubsubhuddle-realtime-web.pdf">PubSubHuddle - Realtime Web PDF</a> (5MiB) <a href="http://www.scribd.com/doc/66379391">(Scribd)</a> </li>
</ul>

<p>The slides are rather terse, in order to understand them you may
want to listen to the talk:</p>

<ul>
<li><a href="http://skillsmatter.com/podcast/nosql/marek-majkowski-talk">Skills Matter recording</a></li>
</ul>

<p>For more details about the reasons behind SockJS, read on:</p>

<ul>
<li><a href="https://github.com/sockjs/sockjs-client/wiki/%5BArticle%5D-SockJS:-web-messaging-ain%E2%80%99t-easy">Web messaging ain't easy</a></li>
<li><a href="https://github.com/sockjs/sockjs-client/wiki/%5BArticle%5D-SockJS:-WebSocket-emulation-done-right">WebSocket emulation</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/09/26/pubsubhuddle-realtime-web-talk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sizing your Rabbits</title>
		<link>http://www.rabbitmq.com/blog/2011/09/24/sizing-your-rabbits/</link>
		<comments>http://www.rabbitmq.com/blog/2011/09/24/sizing-your-rabbits/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 11:37:16 +0000</pubDate>
		<dc:creator>Matthew Sackman</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Introductory]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=97</guid>
		<description><![CDATA[One of the problems we face at the RabbitMQ HQ is that whilst we may know lots about how the broker works, we don't tend to have a large pool of experience of designing applications that use RabbitMQ and which need to work reliably, unattended, for long periods of time. We spend a lot of [...]]]></description>
			<content:encoded><![CDATA[<p>One of the problems we face at the RabbitMQ HQ is that whilst we may
know lots about how the broker works, we don't tend to have a large
pool of experience of designing applications that use RabbitMQ and
which need to work reliably, unattended, for long periods of time. We
spend a lot of time answering questions on the mailing list, and we do
consultancy work here and there, but in some cases it's as a result of
being contacted by users building applications that we're really made
to think about long-term behaviour of RabbitMQ. Recently, we've been
prompted to think long and hard about the basic performance of queues,
and this has lead to some realisations about provisioning Rabbits.<span id="more-97"></span></p>

<p>RabbitMQ's queues are fastest when they're empty. When a queue is
empty, and it has consumers ready to receive messages, then as soon as
a message is received by the queue, it goes straight out to the
consumer. In the case of a persistent message in a durable queue, yes,
it will also go to disk, but that's done in an asynchronous manner and
is buffered heavily. The main point is that very little book-keeping
needs to be done, very few data structures are modified, and very
little additional memory needs allocating. Consequently, the CPU load
of a message going through an empty queue is very small.</p>

<p>If the queue is not empty then a bit more work has to be done: the
messages have to actually be queued up. Initially, this too is fast
and cheap as the underlying functional data structures are very
fast. Nevertheless, by holding on to messages, the overall memory
usage of the queue will be higher, and we are doing more work than
before per message (each message is being both enqueued and dequeued
now, whereas before each message was just going straight out to a
consumer), so the CPU cost per message is higher. Consequently, the
top speed you'll be able to achieve with an empty queue will be higher
than the top speed of a queue with a fixed N messages in it, even if N
is very small.</p>

<p>If the queue receives messages at a faster rate than it can pump out
to consumers then things get slower. As the queue grows, it will
require more memory. Additionally, if a queue receives a spike of
publications, then the queue must spend time dealing with those
publications, which takes CPU time away from sending existing messages
out to consumers: a queue of a million messages will be able to be
drained out to ready consumers at a much higher rate if there are no
publications arriving at the queue to distract it. Not exactly rocket
science, but worth remembering that publications arriving at a queue
can reduce the rate at which the queue drives its consumers.</p>

<p>Eventually, as a queue grows, it'll become so big that we have to
start writing messages out to disk and forgetting about them from RAM
in order to free up RAM. At this point, the CPU cost per message is
much higher than had the message been dealt with by an empty queue.</p>

<p>None of this seems particularly profound, but keeping these points in
mind when building your application turns out to be very important.</p>

<p>Let's say you design and build your application, using RabbitMQ. There
will be some set of publishers, and some set of consumers. You test
this, and let's say that in total, in one part of the system, you find
that the maximum rate that'll ensure your queues stay empty or very
near empty is 2000 msgs/second. You then choose a machine on which to
run RabbitMQ, which might be on some sort of virtual server. When
testing at 2000 msgs/second you found the CPU load of the box running
RabbitMQ was not very high: the bottleneck was elsewhere in the
application -- most likely in the consumers of your queues (you were
measuring the maximum stable end-to-end performance) -- so RabbitMQ
itself wasn't being overly stressed and so wasn't eating up much
CPU. Consequently, you choose a virtual server which isn't enormously
powerful. You then launch the application and sure enough, everything
looks OK.</p>

<p>Over time, your application becomes more popular, and so your rates
increase.</p>

<p>Eventually, you get to a point where your consumers are running flat
out, and your queues are staying nearly empty. But then, at the most
popular time of the day for your application, your publishers push a
few more messages into your queues than before. This is just normal
growth -- you have more users now and so it's not surprising messages
are being published a bit faster than before. What you hope will
happen is that RabbitMQ will just happily buffer up the messages and
will eventually feed them to your consumers who will be able to work
through the back-log during quieter times of the day.</p>

<p>The problem is that this might not be able to happen. Because your
queues are now (albeit briefly) receiving more messages than your
consumers can cope with, the queues spend more CPU time dealing with
each message than they used to when the queue was empty (the messages
now have to be queued up). That takes away CPU time from driving the
consumers and unfortunately, as you chose a machine for RabbitMQ which
didn't have a great deal of spare CPU capacity, you start maxing out
the CPU. Thus your queues can't drive your consumers quite as hard as
before, which in turn makes the rate of growth of the queues
increase. This in turn starts to push the queues to sizes where they
have to start pushing messages to disk in order to free up RAM which
again takes up more CPU which you don't have, and by this point,
you're likely in deep trouble.</p>

<p>What can you do?</p>

<p>At this immediate point, you need to get your queues drained. Because
your queues are spending more time dealing with new messages arriving
than with pushing messages out to consumers, it's unlikely that
throwing more consumers at the queues is going to significantly
help. You really need to get the publishers to stop.</p>

<p>If you have the luxury of just turning off the publishers then do
that, and turn them back on when the queues become empty again. If you
can't do that, then you need to divert their load somewhere else, but
given that your Rabbit is writing out to disk to avoid running out of
memory, and is maxing out the CPU, adding new queues to your current
Rabbit is not going to help -- you need a new Rabbit on a different
machine. If you've set up a cluster, then you could provision new
queues on a node of your RabbitMQ cluster that is not so heavily
loaded, then attach lots of new consumers to that, and divert the
publishers into there. At this point, you'll realise the value of not
using the default nameless exchange and addressing queues directly,
and instead will be very glad that you had your publishers publish to
an exchange you created, thus allowing you to add a new binding to
your fresh new queue, and deleting the binding to your old queue,
diverting the load, and not having to interrupt your publishers at
all. The old queues will then be able to drive their consumers (which
you've not removed!) as fast as possible, and the queues will
drain. Now in this situation, you have the prospect of messages being
processed out of order (new messages arriving in the fresh new queues
may be processed by your new consumers before the old messages in the
old queues are processed), but if you have multiple consumers off a
single queue then you're probably already dealing with that problem
anyway.</p>

<p>Prevention, we are often told, is preferable to cure. So how could you
design your application to be able to help RabbitMQ cope with these
potentially catastrophic situations?</p>

<p>Firstly, don't use a very low <code>basic.qos</code> prefetch value in
your consumers. If you use a value of 1 then it'll mean that a queue
sends out one message to a consumer, and then can't send anything more
to that consumer until it receives the acknowledgement back. Only when
it's done that can it send out the next message. If it takes a while
for the acknowledgement to make its way back to the queue (for
example, high latency on the network, or the load that your Rabbit is
under may mean it takes a while for that acknowledgement to get all
the way through to the queue) then in the meantime, that consumer is
sitting there idle. If you use a <code>basic.qos</code> prefetch value
of 20, for example, then the broker will ensure that 20 messages are
sent to the consumer, and then even as the acknowledgement for the
first message is (maybe slowly) making its way back to the queue, the
consumer still has work to be getting on with (i.e. the next 19
messages). Essentially, the higher the prefetch value, the greater
insulation the consumer has from spikes in the round trip time back to
the queue.</p>

<p>Secondly, consider not acknowledging every message, but instead
acknowledging every N messages and setting the <code>multiple</code>
flag on the acknowledgement. When the queue is overloaded, it's
because it has too much work to do (profound, I know). As a consumer,
you can reduce the amount of work it has to do by ensuring you don't
flood it with acknowledgements.  Thus, for example, you set the
<code>basic.qos</code> prefetch to 20, but you only send an
acknowledgement after you've processed every 10 messages and you set
the <code>multiple</code> flag to true on the acknowledgement. The
queue will now receive one-tenth of the acknowledgements it would have
previously received. It will still internally acknowledge all ten
messages, but it can do it in a more efficient way if it receives one
acknowledgement that accounts for several messages, rather than lots
of individual acknowledgements. However, if you're only acknowledging
every N messages, be sure that your <code>basic.qos</code> prefetch
value is higher than N. Probably at least 2*N. If your prefetch value
is the same as N, then your consumer will once again be left idle
whilst the acknowledgement makes its way back to the queue and the
queue sends out a fresh batch of messages.</p>

<p>Thirdly, have a strategy to pivot the load to other queues on others
machines if the worst comes to the worst. Yes, it is a good idea to
use RabbitMQ as a buffer which insulates publishers from consumers and
can absorb spikes. But equally, you need to remember that RabbitMQ's
queues go fastest when they're empty, and we always say that you
should design your application so that the queues are normally
empty. Or to put it another way, the performance of a queue is lowest
when you likely need more than ever for it to absorb a large
spike. The upshot of that is that unless you test to makes sure you
know it will recover, you might be in for a surprise should a
non-trivial spike occur which substantially increases the length of
your queues. You may not have factored into your thinking that in such
a situation, your existing consumers may end up being driven more
slowly than before, simply because your queues are busy doing other
things (enqueuing messages), and that this can cause a vicious cycle
that eventually results in a catastrophic loss of performance of the
queue.</p>

<p>The nub of the issue is that a queue is a single-threaded resource. If
you've designed your routing topology in such a way that it already
does, or at least can, spread messages across multiple queues rather
than just hammering all messages into a single queue, then you're far
more likely to be able to respond to such problems occurring quickly
and easily, by diverting load and being able to take advantage of
additional CPU resources which ensure that you can minimise the
CPU-hit per message.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/09/24/sizing-your-rabbits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PubSub huddle</title>
		<link>http://www.rabbitmq.com/blog/2011/09/16/pubsub-huddle/</link>
		<comments>http://www.rabbitmq.com/blog/2011/09/16/pubsub-huddle/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 07:28:26 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Talks and conferences]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[messaging]]></category>
		<category><![CDATA[pubsub]]></category>
		<category><![CDATA[pubsubhuddle]]></category>
		<category><![CDATA[skillsmatter]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=96</guid>
		<description><![CDATA[All of a sudden there's just one week to go until the PubSub huddle. It's a one day conference, in London, about messaging. Not just RabbitMQ, but ZeroMQ, MQTT, XMPP and PuSH. It's free as in beer. There's free beer. And, at last count, there's spaces left. We have some neat talks lined up Martin [...]]]></description>
			<content:encoded><![CDATA[<p>All of a sudden there's just one week to go until the <a href="http://www.pubsubhuddle.com/">PubSub huddle</a>. It's a one day conference, in London, about messaging. Not just RabbitMQ, but ZeroMQ, MQTT, XMPP and PuSH.</p>

<p><strong>It's free as in beer</strong>. <em>There's free beer</em>. And, at last count, there's <a href="http://skillsmatter.com/event/nosql/pubsub">spaces left</a>.</p>

<h3>We have some neat talks lined up</h3>

<ul>
<li>Martin Sústrik -- <strong>The Future of Messaging</strong></li>
<li>Andy Piper -- <strong>Introducing MQTT</strong></li>
<li>Marek Majkowski -- <strong>Realtime web: Not there yet!</strong></li>
<li>Julien Genestoux -- <strong>PubSub for the web : PubSubHubbub, XMPP and Superfeedr</strong></li>
</ul>

<p>(<a href="http://pubsubhuddle.com/node/1">full descriptions</a>)</p>

<p>If you can't come along, do not fret. The talks will all be taped.</p>

<p>If you can come along, here's the important bit: <strong style="font-size: larger">we want you to bring along your own projects</strong> (and laptops). Because in the afternoon, we'll be asking for people to stand up and give a quick talk about what they are doing with messaging, then we'll all break out into huddles. This is your chance to win people to your cause -- or to find a great project to get involved in.</p>

<p>We'll have the speakers and various RabbitMQ and ZeroMQ folk floating around, so it's also your chance to put them on the spot.</p>

<h3>pubsubwhatnow?</h3>

<p>Going back a few years, James Governor suggested there was an emerging community
of people who cared about messaging and that we should all meet up.  Thus
was born an occasional series of events called "PubSub - putting the pub back into
pubsub". Many people you'll see at the huddle went to those pubs.</p>

<p>The idea of a conference came during the ZeroMQ meetup in Brussels,
when someone said "wouldn't it be great to bring <em>messaging</em> folks together for a day?" -- RabbitMQ or ZeroMQ, we think messaging is fundamental.</p>

<p>To make it happen, we partnered with <a href="http://www.skillsmatter.com/">Skills Matter</a>, who know a thing or two about running this kind of event.</p>

<h3>You said free beer?</h3>

<p>Yes. We're providing coffee and tea, lunch, and later on beer and pizza, courtesy of VMware. <a href="http://skillsmatter.com/event/nosql/pubsub">Register for your free beer and conference here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2011/09/16/pubsub-huddle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

