Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
0MQ: A new approach to messaging (lwn.net)
89 points by signa11 on Jan 28, 2010 | hide | past | favorite | 32 comments


One of the really nice things about 0mq is that it takes care of all the annoying bits, without doing too much to your "networking model". By way of example: I was at the middlware2009 conference, and I was implementing algorithms that presenters and their papers discussed, and doing it very quickly because of 0mq. Basically hundreds of lines of code about 'crap i need to send that to x,y and z' went away. Lots of other little details like that went away too -- sockets without the mess. On the other end, I did not have to try and rework various algroithms in terms of overt pub/sub channels, or message queue parameters. It is a good product.


Good article, and some excellent comments at the end including a discussion of AMQP v.s. 0MQ v.s. RestMS from someone who has been involved in the design of all three.


I'm still hoping for a simple protocol with strong guarantees and persistence. RabbitMQ seems to be a very good backend implementation but its the choice of AMQP for the main protocol is a pity.

AMQP is a ridiculously over-engineered monstrosity and a saturn-sized ball on a chain for any project.


Seriously. Roll your own over Redis.

Redis is faster than BeanStalkd, a tiny message queue server written in C that uses libevent and a simple memcached-like protocol. Redis kicks ass, specially the beta versions.


beanstalkd is not really a message queue, its a job queue. I understand that job vs message can get into semantic nonsense, but in essence a message queue can and will send any given message to n people. A job queue will only send it to the first requester. Redis does kick butt, but a k/v store is not the same as a broacast (or 1toMany, or many to one) meassage store, is not the same as a 'give me the next job' (1toAny) server either.


If Redis uses TCP it will bottleneck long before 0MQ does, because 0MQ uses a reliable-multicast protocol for communication over the LAN. As discussed in the linked article, in the comments.

Also, Redis is a centralized server and a single point of failure - 0MQ doesn't force you into that topology.


Redis is a k/v store, not a queue.


Actually Redis is a bit more than a k/v store these days. It provides implementations of a variety of basic data structures, including lists that support queue operations. There's BLPOP[1] and BRPOP for blocking job/message requests and LPUSH and RPUSH for placing a job/message on the queue.

That said, I'd still like to see benchmarks showing Redis beating Beanstalkd. Of the two, I've only used Beanstalkd, but it's a great example of keeping things simple while still providing advanced functionality.

_

1 http://code.google.com/p/redis/wiki/BlpopCommand


Key == mailbox/slot, and value == message. All you need are concurrency primitives, and broadcasting (in the case of a distributed queue)

People have modeled message queues with far more primitive solutions:

http://www.freeopenbook.com/php-hacks/phphks-CHP-5-SECT-18.h...

A Redis based solution might not be as elaborate as RabbitMQ, but it will be very clean and straightforward, not to mention blindingly fast, and will get the job done.


Well, I'm quite skeptical about the "blindingly fast" part (network overhead?) but agree that in the light of the current mq-options that's indeed one of the more appealing ideas.

That said, I'm not really in the mood to reinvent that particular wheel myself here, but would probably give someone else's shot a try.


How exactly would you do this with Redis? Redis does not push out data to N > 1 listeners/observers/subscribers. I suppose you could use either SYNC and pretend to be a replication slave, MONITOR and watch for RPUSH, or BLPOP. BLPOP hangs/blocks the client though.

Sure, the Redis C codebase is fairly approachable. Perhaps you were suggesting adding new protocol commands?


By what metric is redis faster than beanstalkd?

Does redis has any job queue facilities for making a reliable, low-latency, safe job queue?

http://www.rockstarprogrammer.org/post/2008/oct/04/what-matt...


Yes, it does. See the LPOPRPUSH and BLPOP protocol commands. There's a number of threads on the Redis Google Group about using Redis as a job queue. There's also Resque by a githubber.

http://github.com/defunkt/resque


RPOPLPUSH does about half of what's needed and BLPOP does the other half, but neither does the whole job.

It's not interesting to discuss what you can use to hack a queue together. Lots and lots of really badly thought out queue services exist today built on top of memcached or a relational database or other things that appear to work in normal cases, but can go horribly wrong and start losing data when bad things happen.


I'm curious, what do you feel is overengineered about AMQP?

I've been using it for a while, and I find it to be quite simple. I send messages based on a routing key. They go to the right place, and reasonably fast (though not as fast as zeromq). What's overengineered about it?


Well, for starters try to find a good AMQP tutorial. There's Rabbits & Warrens (which is good but still quite rough) and that's about it. Large parts of the semantics (exchange types, interactions between the various flags) are needlessly complex. Most of the same could have been achieved with much simpler primitives (see other protocols like spread, stomp etc.).

Even one of the authors in this article admits dumb decisions like making it a binary protocol and generally making it extra-ordinarily difficult to create a working protocol endpoint. What's up with this whole XML descriptor thing...

In summary AMQP has been the most painful protocol I had the misfortune to work with since leaving java-land. (Admittedly partly because the python drivers are especially messy)


That's interesting - my experience has been the opposite (that is, AMQP has been quite easy to work with), but I wonder if it's because I primarily use the Ruby clients (http://github.com/tmm1/amqp for asynchronous, http://github.com/celldee/bunny for synchronous)? I've also used the Erlang client a bit, which was somewhat trickier. Maybe this should inspire me to start a blog and write up a tutorial.


It isn't just ruby clients, I've found the python client to be similarly simple. I get the impression that there can be a lot of complexity to AMQP - but so far the c and python client libraries have hidden nearly all of it from me.


Look into the DDS protocol -- various implementations exist, and many of the features you want are available. I believe the open source implementation is called OpenSplice


I've been looking at beanstalk, and I like what I see.

Simple protocol, main implementation 6000 lines of non-awful C, libevent... What's not to like?

http://kr.github.com/beanstalkd/


From one of the comments on that page:

"Likewise, neither 0MQ nor AMQP works on Internet scales, where RESTful principles become more important than immediate performance."

I don't follow this logic. Can someone help me understand why 0MQ would not be appropriate at "Internet scales" (and I presume "should" be relegated to LANs)?

I ask because (1) it looks great for a general transport at any "scale" and (2) the article itself discusses a scenario in which 0MQ could be used over a WAN (branch offices, the forwarder, etc.).

What am I missing?


I think what he is saying is that a general internet "service" is better off providing a higher-level REST interface instead of a 0MQ interface.


OK, I suppose the keyword there is "general". In that context I cannot argue with the idea.


I found this too:

"Yup. Seen that one [UDT]. However, AFAIU, it focuses on moving large messages over high-latency high-volume links. 0MQ is focused on short messages on low-latency high-volume links."

http://lists.zeromq.org/pipermail/zeromq-dev/2009-August/001...


Looks interesting, but the documentation is still incomplete. For example, the zmq_connect() docs don't list error codes for name lookup failure, connect timeout, or connection reset. There also don't seem to be sockopts for setting timeout lengths.

Looking at the API, how could my application detect that messages aren't being delivered to a particular peer?


We're working on the documentation, but don't let that stop you from joining in and helping us improve it!

As for detecting that messages aren't being delivered to a particular peer, at the moment that is not possible since zmq_send() is asynchronous from the point of view of the caller, i.e. the actual sending gets offloaded to a background thread.

Unfortunately there's no straightforward way to map asynchronous error handling onto the socket API. I guess we could experiment with hitting the calling thread with a SIGPIPE or similar but signal handling on a lot of systems is suboptimal (to put it politely) and we also need to support Win32. So this whole area requires more thought...


It's usually written as ZeroMQ, FWIW.


Im not sure where you get your info, on the dev list 0mq, zmq (and zmq_$COMPONENT) and zeromq are pretty evenly distrbuted...

(edit: yoru -> your)


Just as a simple test, 0mq.com redirects to zeromq.com :-)

Also, if all three are evenly distributed, then that makes the letter prefix preferable to the digit prefix 2:1.

In any event, I think "0mq" looks ugly and people might mistake it for "OMG".


Actually, all over the front page I see ØMQ, not 0MQ. It's read "zero", but it's spelled with a slashed capital O.


Many fonts use a slash or a dot in the center of the zero in order to distinguish it clearly from capital-oh. i.e. It's clear to me they are branding this as 0MQ.


True story. In my teens I got a hold of the BBC Micro assembly programming manual; 6502, in all its 8-bit glory. I didn't understand much English, and I haven't had much 1-on-1 time with a computer in my life (paper hacking) so when I got that book, I was completely dumbfounded and confused by the zero with a strike through. I have never seen this symbol before in my life, and now I don't see it anywhere on the keyboard. sigh.

Good news though. A few months later I was programming in Forth, learning from a self-xeroxed copy of Starting Forth, and it had the zero-slash everywhere. I am not sure when did I realize that Ø == 0. (It looks like the empty set, aka "phi" Φ)

[Edit: http://en.wikipedia.org/wiki/%C3%98_%28disambiguation%29 ]




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: