<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Redis and Ruby</title>
	<atom:link href="http://www.programmersparadox.com/2009/06/02/redis-and-ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.programmersparadox.com/2009/06/02/redis-and-ruby/</link>
	<description>Long form thoughts from a Software Engineer</description>
	<lastBuildDate>Thu, 19 Jan 2012 13:42:07 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Mark Mzyk</title>
		<link>http://www.programmersparadox.com/2009/06/02/redis-and-ruby/comment-page-1/#comment-25220</link>
		<dc:creator>Mark Mzyk</dc:creator>
		<pubDate>Wed, 27 Apr 2011 02:47:45 +0000</pubDate>
		<guid isPermaLink="false">http://www.programmersparadox.com/?p=844#comment-25220</guid>
		<description>Thanks for the examples Jim.  You&#039;re right in that Redis can be used as much more than a simple key value store.  I was only just starting to explore Redis when I wrote this blog post, although I still haven&#039;t done as much as I would like.  I appreciate the code showing the versatility of a tool like Redis.  I hadn&#039;t considered using it for producers and consumers.</description>
		<content:encoded><![CDATA[<p>Thanks for the examples Jim.  You&#8217;re right in that Redis can be used as much more than a simple key value store.  I was only just starting to explore Redis when I wrote this blog post, although I still haven&#8217;t done as much as I would like.  I appreciate the code showing the versatility of a tool like Redis.  I hadn&#8217;t considered using it for producers and consumers.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jim Dennis</title>
		<link>http://www.programmersparadox.com/2009/06/02/redis-and-ruby/comment-page-1/#comment-25213</link>
		<dc:creator>Jim Dennis</dc:creator>
		<pubDate>Tue, 26 Apr 2011 08:59:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.programmersparadox.com/?p=844#comment-25213</guid>
		<description>Hmmm ... to play with redis using Python on my Debian box I just typed:

    sudo aptitude install redis-doc redis-server python-redis

... the started ipython, and played with it using:

   import redis
   r = redis.Redis()
   r.keys()
   r.set(&#039;foo&#039;, &#039;bar&#039;)
   r.set(&#039;counter&#039;, 0)
   r.incr(&#039;counter&#039;)
   [r.rpush(&#039;somelist&#039;, x) for x in range(10)]
   r.lrange(&#039;somelist&#039;, 0, r.llen(&#039;somelist&#039;)

... and so on.

Which leads me to my main point:  if you think of Redis as a simple key/value store then you are missing out on its best features.  The fact that it supports several types of data (strings, numbers, lists, sets, ordered sets, and hash maps) and a number of coherent/atomic operations on those (increments, pushes and pops, and blocking pops with timeouts, for example) makes Redis a versatile general purpose way for co-ordinating distributed processes.

For example it&#039;s almost trivial to write code to implement a multi-producer/multi-consumer work distribution model through a Redis server.

For example the following implements a simple consumer:

    while r.get(&#039;mystatus&#039;) != &#039;Done&#039;:
        poll = r.blpop([&#039;q1&#039;, &#039;q2&#039;, ...], timeout)
        if poll is not None:
            # do periodic clean-up
            continue
        key, value = poll
        # dispatch values into handlers by key ...

This is similar to a select() driven event model, but simpler and at a much higher level (without any low level socket handling issues).  (Yes, you might have to wrap this all in an exception handler to catch connection lossage but even with that it&#039;s simpler than writing this with raw sockets and select()).

Additionally Redis supports a simple publish/subscribe feature.  While the example above would ensure that each value pushed into any queue (key storing a list) was popped off by exactly one consumer ... the publish/subscribe allows a number of clients to all get notification of events.  (Imagine if &quot;mystatus&quot; in the above example had states for &quot;Paused&quot; as well as &quot;Done&quot; and the implicit &quot;Running&quot;; the clients could all then subscribe to an event channel and do a blocking .listen() call to receive notification of events. This might be an absurdly simplistic use of the publish/subscribe feature but it builds easily on the previous model).</description>
		<content:encoded><![CDATA[<p>Hmmm &#8230; to play with redis using Python on my Debian box I just typed:</p>
<p>    sudo aptitude install redis-doc redis-server python-redis</p>
<p>&#8230; the started ipython, and played with it using:</p>
<p>   import redis<br />
   r = redis.Redis()<br />
   r.keys()<br />
   r.set(&#8216;foo&#8217;, &#8216;bar&#8217;)<br />
   r.set(&#8216;counter&#8217;, 0)<br />
   r.incr(&#8216;counter&#8217;)<br />
   [r.rpush('somelist', x) for x in range(10)]<br />
   r.lrange(&#8216;somelist&#8217;, 0, r.llen(&#8216;somelist&#8217;)</p>
<p>&#8230; and so on.</p>
<p>Which leads me to my main point:  if you think of Redis as a simple key/value store then you are missing out on its best features.  The fact that it supports several types of data (strings, numbers, lists, sets, ordered sets, and hash maps) and a number of coherent/atomic operations on those (increments, pushes and pops, and blocking pops with timeouts, for example) makes Redis a versatile general purpose way for co-ordinating distributed processes.</p>
<p>For example it&#8217;s almost trivial to write code to implement a multi-producer/multi-consumer work distribution model through a Redis server.</p>
<p>For example the following implements a simple consumer:</p>
<p>    while r.get(&#8216;mystatus&#8217;) != &#8216;Done&#8217;:<br />
        poll = r.blpop(['q1', 'q2', ...], timeout)<br />
        if poll is not None:<br />
            # do periodic clean-up<br />
            continue<br />
        key, value = poll<br />
        # dispatch values into handlers by key &#8230;</p>
<p>This is similar to a select() driven event model, but simpler and at a much higher level (without any low level socket handling issues).  (Yes, you might have to wrap this all in an exception handler to catch connection lossage but even with that it&#8217;s simpler than writing this with raw sockets and select()).</p>
<p>Additionally Redis supports a simple publish/subscribe feature.  While the example above would ensure that each value pushed into any queue (key storing a list) was popped off by exactly one consumer &#8230; the publish/subscribe allows a number of clients to all get notification of events.  (Imagine if &#8220;mystatus&#8221; in the above example had states for &#8220;Paused&#8221; as well as &#8220;Done&#8221; and the implicit &#8220;Running&#8221;; the clients could all then subscribe to an event channel and do a blocking .listen() call to receive notification of events. This might be an absurdly simplistic use of the publish/subscribe feature but it builds easily on the previous model).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mark Mzyk</title>
		<link>http://www.programmersparadox.com/2009/06/02/redis-and-ruby/comment-page-1/#comment-7942</link>
		<dc:creator>Mark Mzyk</dc:creator>
		<pubDate>Wed, 30 Sep 2009 20:34:06 +0000</pubDate>
		<guid isPermaLink="false">http://www.programmersparadox.com/?p=844#comment-7942</guid>
		<description>Good point, runeb.  At the time, I didn&#039;t realize that github could be set as a gem source.  Thanks for pointing that out so that now everyone else knows as well.  That way is much easier.</description>
		<content:encoded><![CDATA[<p>Good point, runeb.  At the time, I didn&#8217;t realize that github could be set as a gem source.  Thanks for pointing that out so that now everyone else knows as well.  That way is much easier.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: runeb</title>
		<link>http://www.programmersparadox.com/2009/06/02/redis-and-ruby/comment-page-1/#comment-7908</link>
		<dc:creator>runeb</dc:creator>
		<pubDate>Sun, 27 Sep 2009 14:34:13 +0000</pubDate>
		<guid isPermaLink="false">http://www.programmersparadox.com/?p=844#comment-7908</guid>
		<description>Or do:
gem sources -a http://gems.github.com
gem install ezmobius-redis-rb</description>
		<content:encoded><![CDATA[<p>Or do:<br />
gem sources -a <a href="http://gems.github.com" rel="nofollow">http://gems.github.com</a><br />
gem install ezmobius-redis-rb</p>
]]></content:encoded>
	</item>
</channel>
</rss>

