Nanomsg: ZeroMQ done right

Presenter Notes

whoami

Haïkel Guémar

Fedora Packager since 2006

Senior Software Engineer @ SysFera

Presenter Notes

Nanomsg

Presenter Notes

Few facts

  • Written by Martin Sustrik (co-creator of ZeroMQ)

  • MIT licensed

  • Release 0.1 alpha (20 august 2013)

  • Release 0.2 alpha (25 september 2013)

Presenter Notes

A bite of history

  • iMatix: a company run by Pieter Hintjens
  • iMatix created AMQP as a contractor for JP Morgan
  • AMQP == centralized broker
  • iMatix left the AMQP standard committee due to disagreement
  • In reaction to AMQP, they created AMQP

Presenter Notes

ZeroMQ

  • Networking library
  • But acts as a concurrency framework (Actor oriented)
  • Various transports: in-process, inter-process, tcp, pgm
  • Various patterns (aka Protocols): fan-out, pub/sub, request/reply etc.
  • Think connected applications fabric
  • Ease creating scaling applications
  • LGPLv3

Presenter Notes

Zen of Zero

Zero

  • broker
  • latency (best effort)
  • administration
  • cost
  • waste

Presenter Notes

A friendly fork

Sustrik wanted:

  • standardize ZeroMQ network protocol
  • integration with Linux kernel
  • move to MIT license

No drama, few jokes and encouragements from both sides

Presenter Notes

Crossroads I/O

  • Technically a (compatible) fork of ZeroMQ
  • It failed but Sustrik learnt a lot

Presenter Notes

Nanomsg

  • A reboot of ZeroMQ

Presenter Notes

Why Nanomsg (and Not ZeroMQ ?)

Presenter Notes

Advantages

  • Aims POSIX full-compliance

  • Written in C

  • API for integrating new protocols and transports

  • command-line tools (nanocat)

Presenter Notes

Goodbye context !

/* with zeromq */
void *ctx = zmq_ctx_new ();
void *s = zmq_socket (ctx, ZMQ_PUSH);
zmq_connect (s, "tcp://192.168.0.111:5555");
zmq_send (s, "ABC", 3, 0);
zmq_close (s);
zmq_ctx_destroy (ctx);
/* with nanomsg */
int s = nn_msg(AF_SP, NN_PUSH);
nn_connect(s, "tcp://192.168.0.111:5555");
nn_send(s, "ABC", 3, 0);
nn_close(s);  /* attention, appel désormais bloquant */

Presenter Notes

Performances and safety ?

  • In C
  • Use intrusive containers instead of STL
  • Use IOCP on Windows
  • Level-triggered polling
  • Objects are no more tied to a thread
  • Interactions are now associated to state machines
  • Asynchronous DNS calls

Presenter Notes

Remember, i told you so !

Presenter Notes

Really zero-copy

void *buf = nn_allocmsg(12, 0);
memcpy(buf, "Hello world!", 12);
nn_send(s, &buf, NN_MSG, 0);
nn_recv(s, &buf, NN_MSG, 0);
nn_freemsg(buf);

Presenter Notes

nanocat

  • command line tool for testing and debugging purpose
  • provides many symlinks to simplify user interface
  • supports msgpack

Presenter Notes

Nanocat (sample)

# server-side
nanocat --rep --bind tcp://127.0.0.1:8000 --format ascii --data pong
# client side
nanocat --req --connect tcp://127.0.0.1:8000 --format ascii --data ping

Presenter Notes

Nanocat (sample)

!bash nanocat --pub --connect tcp://darthsidious --data "My liege !" --interval 10

Presenter Notes

Protocol

Presenter Notes

Pair Protocol

Presenter Notes

Pair Protocol (client)

int sock = nn_socket(AF_SP, NN_PAIR);
nn_connect(sock, url);
nn_send(sock, "hello", 6, 0);
char *buf = NULL;
int result = nn_recv(sock, &buf, NN_MSG, 0);
nn_freemsg(buf);
nn_shutdown(sock, 0);

Presenter Notes

Pair Protocol (server)

int sock = nn_socket(AF_SP, NN_PAIR);
nn_bind(sock, url);
char *buf = NULL;
int result = nn_recv(sock, &buf, NN_MSG, 0);
nn_freemsg(buf);
nn_send(sock, "kthxbye", 8, 0);
nn_shutdown(sock, 0);

Presenter Notes

Request/Reply Protocol

Presenter Notes

Request/Reply Protocol (client)

int sz_msg = strlen(msg) + 1;
int sock = nn_socket(AF_SP, NN_REQ);
nn_connect(sock, url);
int bytes = nn_send(sock, msg, sz_msg, 0);
nn_shutdown(sock, 0);

Presenter Notes

Request/Reply Protocol (server)

int sock = nn_socket(AF_SP, NN_REP);
nn_bind(sock, url);
while (1) {
  char *buf = NULL;
  int bytes = nn_recv(sock, &buf, NN_MSG, 0);
  nn_freemsg(buf);
}

Presenter Notes

Pipeline Protocol

Presenter Notes

Pipeline Protocol (client)

int sz_msg = strlen(msg) + 1;
int sock = nn_socket(AF_SP, NN_PUSH);
nn_connect(sock, url);
int bytes = nn_send(sock, msg, sz_msg, 0);
nn_shutdown(sock, 0);

Presenter Notes

Pipeline Protocol (server)

int sock = nn_socket(AF_SP, NN_PULL);
nn_bind(sock, url);
while (1) {
  char *buf = NULL;
  int bytes = nn_recv(sock, &buf, NN_MSG, 0);
  nn_freemsg(buf);
}

Presenter Notes

Survey Protocol

Presenter Notes

Survey Protocol

Presenter Notes

Survey Protocol

  • NN_SURVEYOR
  • NN_RESPONDENT

Presenter Notes

Bus Protocol

Presenter Notes

Bus Protocol

Presenter Notes

Bus Protocol

  • NN_BUS
  • All nodes receive messages (except the sender !)
  • scales well on a single machine or LAN

Presenter Notes

A lot of bindings

Choose your weapons, cowboy !

C++, Go, Java, node.js, lua/luajit, .Net, OCaml, Perl, PHP, Python, Ruby, Rust

Presenter Notes

Why keep using ZeroMQ ?

  • nanomsg is very young (not production ready)
  • ZeroMQ has an impressive documentation (and its own O'Reilly book)
  • ZeroMQ is good enough
  • Incompatible wire protocols (does not implement ZMTP/1.0 and 2.0)

Presenter Notes

Q/A

Presenter Notes