SlideShare a Scribd company logo
1 of 154
Distributed Systems
 with ZeroMQ and gevent

                 Jeff Lindsay
                 @progrium
Why distributed systems?

 Harness more CPUs and resources
 Run faster in parallel
 Tolerance of individual failures
 Better separation of concerns
Most web apps evolve into
  distributed systems
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
OpenStack
Amazon AWS

                        Provider

Web




                           Provider
 API




Client

                         Provider

   TwiML
ZeroMQ + gevent
Two powerful and misunderstood tools
Concurrency
Heart of Distributed Systems
Distributed computing
is just another flavor of
    local concurrency
Multithreading
         Shared Memory


Thread       Thread        Thread



  Distributed system
         Shared Database


 App          App           App
Concurrency models


Execution model
 Defines the “computational unit”

Communication model
 Means of sharing and coordination
Concurrency models
Traditional multithreading
  OS threads
  Shared memory, locks, etc
Async or Evented I/O
  I/O loop + callback chains
  Shared memory, futures
Actor model
  Shared nothing “processes”
  Built-in messaging
Examples
Erlang
  Actor model
Scala
  Actor model
Go
  Channels, Goroutines
Everything else (Ruby, Python, PHP, Perl, C/C++, Java)
  Threading
  Evented
Erlang is special.


     Normally, the networking of
distributed systems is tacked on to the
       local concurrency model.

            MQ, RPC, REST, ...
Why not always use Erlang?
Why not always use Erlang?
Half reasons
 Weird/ugly language
 Limited library ecosystem
 VM requires operational expertise
 Functional programming isn’t mainstream
Why not always use Erlang?
Half reasons
  Weird/ugly language
  Limited library ecosystem
  VM requires operational expertise
  Functional programming isn’t mainstream
Biggest reason
  It’s not always the right tool for the job
Amazon AWS

                        Provider

Web




                           Provider
 API




Client

                         Provider

   TwiML
Service Oriented
  Architecture
    Multiple languages
   Heterogeneous cluster
RPC
RPC
Client / server
RPC
Client / server
Mapping to functions
RPC
Client / server
Mapping to functions
Message serialization
RPC
       Client / server
       Mapping to functions
       Message serialization

Poor abstraction of what you really want
What you want are tools to help you get distributed
actor model concurrency like Erlang ... without Erlang.
     Even better if they're decoupled and optional.
Rarely will you build an application as
part of a distributed system that does
   not also need local concurrency.
Communication model

How do we unify communications in local concurrency
     and distributed systems across languages?
Execution model

How do we get Erlang-style local concurrency without
 interfering with the language's idiomatic paradigm?
ZeroMQ
Communication model
Misconceptions
Misconceptions

It’s just another MQ, right?
Misconceptions

It’s just another MQ, right?
   Not really.
Misconceptions

It’s just another MQ, right?
   Not really.
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.

Wait, isn’t messaging a solved problem?
Misconceptions

It’s just another MQ, right?
   Not really.

Oh, it’s just sockets, right?
 Not really.

Wait, isn’t messaging a solved problem?
 *sigh* ... maybe.
Regular Sockets
Regular Sockets


Point to point
Regular Sockets


Point to point
Stream of bytes
Regular Sockets


Point to point
Stream of bytes
Buffering
Regular Sockets


Point to point
Stream of bytes
Buffering
Standard API
Regular Sockets


Point to point
Stream of bytes
Buffering
Standard API
TCP/IP or UDP, IPC
Messaging
Messaging
Messages are atomic
Messaging
Messages are atomic
Messaging
Messages are atomic
Messaging
Messages are atomic
Messaging
Messages are atomic   Messages can be routed
Messaging
Messages are atomic   Messages can be routed
Messaging
Messages are atomic   Messages can be routed
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around   Messages are delivered
Messaging
 Messages are atomic      Messages can be routed




Messages may sit around   Messages are delivered
Rise of the Big MQ
App
      App




               Reliable
            Message Broker


               Persistent
                 Queues
                                   App
App
App
      App




                  App
App
AMQP

            MQ




Producer
                  Consumer
AMQP

                           MQ



                      Binding
Producer      X
                                        Consumer
           Exchange             Queue
AMQP

                       MQ




Producer      X
                                    Consumer
           Exchange         Queue
AMQP Recipes
AMQP Recipes
Work queues
Distributing tasks among workers
AMQP Recipes
Work queues                        Publish/Subscribe
Distributing tasks among workers   Sending to many consumers at once



                                           X
AMQP Recipes
Work queues                        Publish/Subscribe
Distributing tasks among workers   Sending to many consumers at once



                                           X




Routing
Receiving messages selectively

             foo

        X     bar

            baz
AMQP Recipes
Work queues                        Publish/Subscribe
Distributing tasks among workers   Sending to many consumers at once



                                           X




Routing                            RPC
Receiving messages selectively     Remote procedure call implementation

             foo

        X     bar

            baz
Drawbacks of Big MQ

   Lots of complexity
   Queues are heavyweight
   HA is a challenge
   Poor primitives
Enter ZeroMQ
“Float like a butterfly, sting like a bee”
Echo in Python
                Server                                     Client

1   import zmq                             1   import zmq
2   context = zmq.Context()                2   context = zmq.Context()
3   socket = context.socket(zmq.REP)       3   socket = context.socket(zmq.REQ)
4   socket.bind("tcp://127.0.0.1:5000")    4   socket.connect("tcp://127.0.0.1:5000")
5                                          5
6   while True:                            6   for i in range(10):
7       msg = socket.recv()                7       msg = "msg %s" % i
8       print "Received", msg              8       socket.send(msg)
9       socket.send(msg)                   9       print "Sending", msg
                                          10       reply = socket.recv()
Echo in Ruby
                 Server                                     Client

 1   require "zmq"                          1   require "zmq"
 2   context = ZMQ::Context.new(1)          2   context = ZMQ::Context.new(1)
 3   socket = context.socket(ZMQ::REP)      3   socket = context.socket(ZMQ::REQ)
 4   socket.bind("tcp://127.0.0.1:5000")    4   socket.connect("tcp://127.0.0.1:5000")
 5                                          5
 6   loop do                                6   (0...10).each do |i|
 7       msg = socket.recv                  7       msg = "msg #{i}"
 8       puts "Received #{msg}"             8       socket.send(msg)
 9       socket.send(msg)                   9       puts "Sending #{msg}"
10   end                                   10       reply = socket.recv
                                           11   end
Echo in PHP
                     Server                                               Client

 1   <?php                                              1   <?php
 2   $context = new ZMQContext();                       2   $context = new ZMQContext();
 3   $socket = $context->getSocket(ZMQ::SOCKET_REP);    3   $socket = $context->getSocket(ZMQ::SOCKET_REQ);
 4   $socket->bind("tcp://127.0.0.1:5000");             4   $socket->connect("tcp://127.0.0.1:5000");
 5                                                      5
 6   while (true) {                                     6   foreach (range(0, 9) as $i) {
 7       $msg = $socket->recv();                        7       $msg = "msg {$i}";
 8       echo "Received {$msg}";                        8       $socket->send($msg);
 9       $socket->send($msg);                           9       echo "Sending {$msg}";
10   }                                                 10       $reply = $socket->recv();
11   ?>                                                11   }
                                                       12   ?>
Bindings

 ActionScript, Ada, Bash, Basic, C, Chicken
 Scheme, Common Lisp, C#, C++, D, Erlang,
F#, Go, Guile, Haskell, Haxe, Java, JavaScript,
 Lua, Node.js, Objective-C, Objective Caml,
  ooc, Perl, PHP, Python, Racket, REBOL,
             Red, Ruby, Smalltalk
Plumbing
Plumbing
Plumbing
Plumbing
Plumbing
Plumbing

inproc
ipc
tcp
multicast
Plumbing

inproc
ipc
tcp
multicast

  socket.bind("tcp://localhost:5560")
  socket.bind("ipc:///tmp/this-socket")
  socket.connect("tcp://10.0.0.100:9000")
  socket.connect("ipc:///tmp/another-socket")
  socket.connect("inproc://another-socket")
Plumbing

inproc
ipc
tcp
multicast

  socket.bind("tcp://localhost:5560")
  socket.bind("ipc:///tmp/this-socket")
  socket.connect("tcp://10.0.0.100:9000")
  socket.connect("ipc:///tmp/another-socket")
  socket.connect("inproc://another-socket")
Plumbing

inproc
ipc
tcp
multicast

  socket.bind("tcp://localhost:5560")
  socket.bind("ipc:///tmp/this-socket")
  socket.connect("tcp://10.0.0.100:9000")
  socket.connect("ipc:///tmp/another-socket")
  socket.connect("inproc://another-socket")
Message Patterns
Message Patterns
Request-Reply


REQ      REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply
       REP


REQ          REP


       REP
Message Patterns
Request-Reply      Publish-Subscribe
       REP                  SUB


REQ          REP     PUB          SUB


       REP                  SUB
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                     SUB


    REQ           REP        PUB          SUB


            REP                     SUB




Push-Pull (Pipelining)
             PULL


     PUSH           PULL


            PULL
Message Patterns
   Request-Reply           Publish-Subscribe
            REP                        SUB


    REQ           REP        PUB             SUB


            REP                        SUB




Push-Pull (Pipelining)              Pair
             PULL


                    PULL     PAIR             PAIR
     PUSH


            PULL
Devices
Queue         Forwarder            Streamer




   Design architectures around devices.
Devices
Queue          Forwarder           Streamer


         REQ                 REP




   Design architectures around devices.
Devices
Queue          Forwarder           Streamer


         PUB                 SUB




   Design architectures around devices.
Devices
Queue           Forwarder           Streamer


         PUSH                PULL




   Design architectures around devices.
Performance
Performance


Orders of magnitude faster than most MQs
Performance


Orders of magnitude faster than most MQs
Higher throughput than raw sockets
Performance


Orders of magnitude faster than most MQs
Higher throughput than raw sockets
 Intelligent message batching
Performance


Orders of magnitude faster than most MQs
Higher throughput than raw sockets
 Intelligent message batching
 Edge case optimizations
Concurrency?
"Come for the messaging, stay for the easy concurrency"
Hintjens’ Law of Concurrency

            e=      mc 2

    E is effort, the pain that it takes
    M is mass, the size of the code
    C is conflict, when C threads collide
Hintjens’ Law of Concurrency
Hintjens’ Law of Concurrency
Hintjens’ Law of Concurrency


         ZeroMQ:
   e=mc 2,   for c=1
ZeroMQ

    Easy       ... familiar socket API
    Cheap      ... lightweight queues in a library
    Fast       ... higher throughput than raw TCP
    Expressive ... maps to your architecture

Messaging toolkit for concurrency and distributed systems.
gevent
Execution model
Threading vs Evented
Evented seems to be preferred for scalable I/O applications
Evented Stack
  Non-blocking Code


    Flow Control


   I/O Abstraction


      Reactor
                       I/O
                      Loop
     Event Poller
1   def lookup(country, search_term):
 2       main_d = defer.Deferred()
 3
 4       def first_step():
 5           query = "http://www.google.%s/search?q=%s" % (country,search_term)
 6           d = getPage(query)
 7           d.addCallback(second_step, country)
 8           d.addErrback(failure, country)
 9
10       def second_step(content, country):
11           m = re.search('<div id="?res.*?href="(?P<url>http://[^"]+)"',
12                         content, re.DOTALL)
13           if not m:
14               main_d.callback(None)
15               return
16           url = m.group('url')
17           d = getPage(url)
18           d.addCallback(third_step, country, url)
19           d.addErrback(failure, country)
20
21       def third_step(content, country, url):
22           m = re.search("<title>(.*?)</title>", content)
23           if m:
24               title = m.group(1)
25               main_d.callback(dict(url = url, title = title))
26           else:
27               main_d.callback(dict(url=url, title="{not-specified}"))
28
29       def failure(e, country):
30           print ".%s FAILED: %s" % (country, str(e))
31           main_d.callback(None)
32
33       first_step()
34       return main_d
gevent


     “Regular” Python


Greenlets       Monkey patching


   Reactor / Event Poller
Green threads
“Threads” implemented in user space (VM, library)
Monkey patching
  socket, ssl, threading, time
Twisted
Twisted
~400 modules
gevent
25 modules
Performance




              http://nichol.as
Performance




              http://nichol.as
Performance




              http://nichol.as
Building a Networking App
 1   #===
 2   # 1. Basic gevent TCP server
 3
 4   from gevent.server import StreamServer
 5
 6   def handle_tcp(socket, address):
 7       print 'new tcp connection!'
 8       while True:
 9           socket.send('hellon')
10           gevent.sleep(1)
11
12   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
13   tcp_server.serve_forever()
1   #===
 2   # 2. Basic gevent TCP server and WSGI server
 3
 4   from gevent.pywsgi import WSGIServer
 5   from gevent.server import StreamServer
 6
 7   def handle_http(env, start_response):
 8       start_response('200 OK', [('Content-Type', 'text/html')])
 9       print 'new http request!'
10       return ["hello world"]
11
12   def handle_tcp(socket, address):
13       print 'new tcp connection!'
14       while True:
15           socket.send('hellon')
16           gevent.sleep(1)
17
18   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
19   tcp_server.start()
20
21   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
22   http_server.serve_forever()
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   def handle_http(env, start_response):
 6       start_response('200 OK', [('Content-Type', 'text/html')])
 7       print 'new http request!'
 8       return ["hello world"]
 9
10   def handle_tcp(socket, address):
11       print 'new tcp connection!'
12       while True:
13           socket.send('hellon')
14           gevent.sleep(1)
15
16   def client_connect(address):
17       sockfile = create_connection(address).makefile()
18       while True:
19           line = sockfile.readline() # returns None on EOF
20           if line is not None:
21               print "<<<", line,
22           else:
23               break
24
25   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
26   tcp_server.start()
27
28   gevent.spawn(client_connect, ('127.0.0.1', 1234))
29
30   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
31   http_server.serve_forever()
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   def handle_http(env, start_response):
 6       start_response('200 OK', [('Content-Type', 'text/html')])
 7       print 'new http request!'
 8       return ["hello world"]
 9
10   def handle_tcp(socket, address):
11       print 'new tcp connection!'
12       while True:
13           socket.send('hellon')
14           gevent.sleep(1)
15
16   def client_connect(address):
17       sockfile = create_connection(address).makefile()
18       while True:
19           line = sockfile.readline() # returns None on EOF
20           if line is not None:
21               print "<<<", line,
22           else:
23               break
24
25   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
26   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
27   greenlets = [
28       gevent.spawn(tcp_server.serve_forever),
29       gevent.spawn(http_server.serve_forever),
30       gevent.spawn(client_connect, ('127.0.0.1', 1234)),
31   ]
32   gevent.joinall(greenlets)
ZeroMQ in gevent?
Lindsay distributed geventzmq
1   from gevent import spawn
 2   from gevent_zeromq import zmq
 3
 4   context = zmq.Context()
 5
 6   def serve():
 7       socket = context.socket(zmq.REP)
 8       socket.bind("tcp://localhost:5559")
 9       while True:
10           message = socket.recv()
11           print "Received request: ", message
12           socket.send("World")
13
14   server = spawn(serve)
15
16   def client():
17       socket = context.socket(zmq.REQ)
18       socket.connect("tcp://localhost:5559")
19       for request in range(10):
20           socket.send("Hello")
21           message = socket.recv()
22           print "Received reply ", request, "[", message, "]"
23
24   spawn(client).join()
Actor model?
Easy to implement, in whole or in part,
       optionally with ZeroMQ
Lindsay distributed geventzmq
What is gevent missing?
What is gevent missing?


    Documentation
What is gevent missing?


    Documentation
    Application framework
gservice
Application framework for gevent
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   def handle_http(env, start_response):
 6       start_response('200 OK', [('Content-Type', 'text/html')])
 7       print 'new http request!'
 8       return ["hello world"]
 9
10   def handle_tcp(socket, address):
11       print 'new tcp connection!'
12       while True:
13           socket.send('hellon')
14           gevent.sleep(1)
15
16   def client_connect(address):
17       sockfile = create_connection(address).makefile()
18       while True:
19           line = sockfile.readline() # returns None on EOF
20           if line is not None:
21               print "<<<", line,
22           else:
23               break
24
25   tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp)
26   http_server = WSGIServer(('127.0.0.1', 8080), handle_http)
27   greenlets = [
28       gevent.spawn(tcp_server.serve_forever),
29       gevent.spawn(http_server.serve_forever),
30       gevent.spawn(client_connect, ('127.0.0.1', 1234)),
31   ]
32   gevent.joinall(greenlets)
1   from gevent.pywsgi import WSGIServer
 2   from gevent.server import StreamServer
 3   from gevent.socket import create_connection
 4
 5   from gservice.core import Service
 6
 7   def handle_http(env, start_response):
 8       start_response('200 OK', [('Content-Type', 'text/html')])
 9       print 'new http request!'
10       return ["hello world"]
11
12   def handle_tcp(socket, address):
13       print 'new tcp connection!'
14       while True:
15           socket.send('hellon')
16           gevent.sleep(1)
17
18   def client_connect(address):
19       sockfile = create_connection(address).makefile()
20       while True:
21           line = sockfile.readline() # returns None on EOF
22           if line is not None:
23               print "<<<", line,
24           else:
25               break
26
27   app = Service()
28   app.add_service(StreamServer(('127.0.0.1', 1234), handle_tcp))
29   app.add_service(WSGIServer(('127.0.0.1', 8080), handle_http))
30   app.add_service(TcpClient(('127.0.0.1', 1234), client_connect))
31   app.serve_forever()
1   from gservice.core import Service
 2   from gservice.config import Setting
 3
 4   class MyApplication(Service):
 5       http_port = Setting('http_port')
 6       tcp_port = Setting('tcp_port')
 7       connect_address = Setting('connect_address')
 8
 9       def __init__(self):
10           self.add_service(WSGIServer(('127.0.0.1', self.http_port), self.handle_http))
11           self.add_service(StreamServer(('127.0.0.1', self.tcp_port), self.handle_tcp))
12           self.add_service(TcpClient(self.connect_address, self.client_connect))
13
14       def client_connect(self, address):
15           sockfile = create_connection(address).makefile()
16           while True:
17               line = sockfile.readline() # returns None on EOF
18               if line is not None:
19                   print "<<<", line,
20               else:
21                   break
22
23       def handle_tcp(self, socket, address):
24           print 'new tcp connection!'
25           while True:
26               socket.send('hellon')
27               gevent.sleep(1)
28
29       def handle_http(self, env, start_response):
30           start_response('200 OK', [('Content-Type', 'text/html')])
31           print 'new http request!'
32           return ["hello world"]
1   # example.conf.py
 2
 3   pidfile = 'example.pid'
 4   logfile = 'example.log'
 5   http_port = 8080
 6   tcp_port = 1234
 7   connect_address = ('127.0.0.1', 1234)
 8
 9   def service():
10       from example import MyApplication
11       return MyApplication()


     # Run in the foreground
     gservice -C example.conf.py

     # Start service as daemon
     gservice -C example.conf.py start

     # Control service
     gservice -C example.conf.py restart
     gservice -C example.conf.py reload
     gservice -C example.conf.py stop

     # Run with overriding configuration
     gservice -C example.conf.py -X 'http_port = 7070'
Generalizing
gevent proves a model that can be implemented in almost
   any language that can implement an evented stack
gevent

 Easy       ... just normal Python
 Small      ... only 25 modules
 Fast       ... top performing server
 Compatible ... works with most libraries

Futuristic evented platform for network applications.
Raiden
 Lightning fast, scalable messaging

https://github.com/progrium/raiden
Concurrency models


Traditional multithreading

Async or Evented I/O

Actor model
Conclusion


Two very simple, but very powerful tools
  for distributed / concurrent systems
Thanks
 @progrium

More Related Content

What's hot

Introduction to ZeroMQ - eSpace TechTalk
Introduction to ZeroMQ - eSpace TechTalkIntroduction to ZeroMQ - eSpace TechTalk
Introduction to ZeroMQ - eSpace TechTalkMahmoud Said
 
FOSDEM 2011 - 0MQ
FOSDEM 2011 - 0MQFOSDEM 2011 - 0MQ
FOSDEM 2011 - 0MQpieterh
 
Distributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqDistributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqRuben Tan
 
RestMS Introduction
RestMS IntroductionRestMS Introduction
RestMS Introductionpieterh
 
Zeromq anatomy & jeromq
Zeromq anatomy & jeromqZeromq anatomy & jeromq
Zeromq anatomy & jeromqDongmin Yu
 
Leveraging zeromq for node.js
Leveraging zeromq for node.jsLeveraging zeromq for node.js
Leveraging zeromq for node.jsRuben Tan
 
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati Python Ireland
 
gen_udp and gen_tcp in Elixir
gen_udp and gen_tcp in Elixirgen_udp and gen_tcp in Elixir
gen_udp and gen_tcp in ElixirTomáš Koutský
 
sshuttle VPN (2011-04)
sshuttle VPN (2011-04)sshuttle VPN (2011-04)
sshuttle VPN (2011-04)apenwarr
 
play framework async with scala
play framework async with scalaplay framework async with scala
play framework async with scalavuhaininh88
 
AHA-best-msf-interface-ever
AHA-best-msf-interface-everAHA-best-msf-interface-ever
AHA-best-msf-interface-everkernelsmith
 
memcached Binary Protocol in a Nutshell
memcached Binary Protocol in a Nutshellmemcached Binary Protocol in a Nutshell
memcached Binary Protocol in a NutshellToru Maesaka
 
Netty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/ConnectivityNetty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/ConnectivityC4Media
 
Let your stuff talk!
Let your stuff talk!Let your stuff talk!
Let your stuff talk!Jeff Prestes
 
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018Codemotion
 

What's hot (20)

NullMQ @ PDX
NullMQ @ PDXNullMQ @ PDX
NullMQ @ PDX
 
Introduction to ZeroMQ - eSpace TechTalk
Introduction to ZeroMQ - eSpace TechTalkIntroduction to ZeroMQ - eSpace TechTalk
Introduction to ZeroMQ - eSpace TechTalk
 
ZeroMQ with NodeJS
ZeroMQ with NodeJSZeroMQ with NodeJS
ZeroMQ with NodeJS
 
ZeroMQ
ZeroMQZeroMQ
ZeroMQ
 
FOSDEM 2011 - 0MQ
FOSDEM 2011 - 0MQFOSDEM 2011 - 0MQ
FOSDEM 2011 - 0MQ
 
Distributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqDistributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromq
 
RestMS Introduction
RestMS IntroductionRestMS Introduction
RestMS Introduction
 
Zeromq anatomy & jeromq
Zeromq anatomy & jeromqZeromq anatomy & jeromq
Zeromq anatomy & jeromq
 
Leveraging zeromq for node.js
Leveraging zeromq for node.jsLeveraging zeromq for node.js
Leveraging zeromq for node.js
 
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
Python Ireland 2012 - Message brokers and Python by Fernando Ciciliati
 
gen_udp and gen_tcp in Elixir
gen_udp and gen_tcp in Elixirgen_udp and gen_tcp in Elixir
gen_udp and gen_tcp in Elixir
 
Zero mq logs
Zero mq logsZero mq logs
Zero mq logs
 
sshuttle VPN (2011-04)
sshuttle VPN (2011-04)sshuttle VPN (2011-04)
sshuttle VPN (2011-04)
 
play framework async with scala
play framework async with scalaplay framework async with scala
play framework async with scala
 
AHA-best-msf-interface-ever
AHA-best-msf-interface-everAHA-best-msf-interface-ever
AHA-best-msf-interface-ever
 
memcached Binary Protocol in a Nutshell
memcached Binary Protocol in a Nutshellmemcached Binary Protocol in a Nutshell
memcached Binary Protocol in a Nutshell
 
Netty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/ConnectivityNetty @Apple: Large Scale Deployment/Connectivity
Netty @Apple: Large Scale Deployment/Connectivity
 
Let your stuff talk!
Let your stuff talk!Let your stuff talk!
Let your stuff talk!
 
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
Gabriele Santomaggio - Inside Elixir/Erlang - Codemotion Milan 2018
 
PHP at Density and Scale
PHP at Density and ScalePHP at Density and Scale
PHP at Density and Scale
 

Similar to Lindsay distributed geventzmq

Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Ontico
 
Scaling application with RabbitMQ
Scaling application with RabbitMQScaling application with RabbitMQ
Scaling application with RabbitMQNahidul Kibria
 
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...Ambassador Labs
 
CocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIsCocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIsTim Burks
 
What I learned about APIs in my first year at Google
What I learned about APIs in my first year at GoogleWhat I learned about APIs in my first year at Google
What I learned about APIs in my first year at GoogleTim Burks
 
The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP Eberhard Wolff
 
Elegant Systems Integration w/ Apache Camel
Elegant Systems Integration w/ Apache CamelElegant Systems Integration w/ Apache Camel
Elegant Systems Integration w/ Apache CamelPradeep Elankumaran
 
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard WolffArchitecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard WolffJAX London
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
Why actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesWhy actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesYaroslav Tkachenko
 
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsMQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsAndy Piper
 
Messaging with RabbitMQ and AMQP
Messaging with RabbitMQ and AMQPMessaging with RabbitMQ and AMQP
Messaging with RabbitMQ and AMQPEberhard Wolff
 
Splunk Conf 2014 - Getting the message
Splunk Conf 2014 - Getting the messageSplunk Conf 2014 - Getting the message
Splunk Conf 2014 - Getting the messageDamien Dallimore
 
NoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePackNoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePackSadayuki Furuhashi
 
NoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePackNoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePackSadayuki Furuhashi
 
Down the RabbitMQ Hole
Down the RabbitMQ HoleDown the RabbitMQ Hole
Down the RabbitMQ HoleBizTalk360
 
Anton Moldovan "Building an efficient replication system for thousands of ter...
Anton Moldovan "Building an efficient replication system for thousands of ter...Anton Moldovan "Building an efficient replication system for thousands of ter...
Anton Moldovan "Building an efficient replication system for thousands of ter...Fwdays
 
Kamailio with Docker and Kubernetes
Kamailio with Docker and KubernetesKamailio with Docker and Kubernetes
Kamailio with Docker and KubernetesPaolo Visintin
 

Similar to Lindsay distributed geventzmq (20)

Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
Построение распределенной системы сбора данных с помощью RabbitMQ, Alvaro Vid...
 
Scaling application with RabbitMQ
Scaling application with RabbitMQScaling application with RabbitMQ
Scaling application with RabbitMQ
 
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
Microservices Practitioner Summit Jan '15 - Don't Build a Distributed Monolit...
 
CocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIsCocoaConf: The Language of Mobile Software is APIs
CocoaConf: The Language of Mobile Software is APIs
 
What I learned about APIs in my first year at Google
What I learned about APIs in my first year at GoogleWhat I learned about APIs in my first year at Google
What I learned about APIs in my first year at Google
 
The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP The Future of Messaging: RabbitMQ and AMQP
The Future of Messaging: RabbitMQ and AMQP
 
WMQ, WMB and EIP
WMQ, WMB and EIPWMQ, WMB and EIP
WMQ, WMB and EIP
 
Elegant Systems Integration w/ Apache Camel
Elegant Systems Integration w/ Apache CamelElegant Systems Integration w/ Apache Camel
Elegant Systems Integration w/ Apache Camel
 
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard WolffArchitecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Why actor-based systems are the best for microservices
Why actor-based systems are the best for microservicesWhy actor-based systems are the best for microservices
Why actor-based systems are the best for microservices
 
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of ThingsMQTT, Eclipse Paho and Java - Messaging for the Internet of Things
MQTT, Eclipse Paho and Java - Messaging for the Internet of Things
 
Messaging with RabbitMQ and AMQP
Messaging with RabbitMQ and AMQPMessaging with RabbitMQ and AMQP
Messaging with RabbitMQ and AMQP
 
Splunk Conf 2014 - Getting the message
Splunk Conf 2014 - Getting the messageSplunk Conf 2014 - Getting the message
Splunk Conf 2014 - Getting the message
 
NoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePackNoSQL afternoon in Japan Kumofs & MessagePack
NoSQL afternoon in Japan Kumofs & MessagePack
 
NoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePackNoSQL afternoon in Japan kumofs & MessagePack
NoSQL afternoon in Japan kumofs & MessagePack
 
Down the RabbitMQ Hole
Down the RabbitMQ HoleDown the RabbitMQ Hole
Down the RabbitMQ Hole
 
Message queueing
Message queueingMessage queueing
Message queueing
 
Anton Moldovan "Building an efficient replication system for thousands of ter...
Anton Moldovan "Building an efficient replication system for thousands of ter...Anton Moldovan "Building an efficient replication system for thousands of ter...
Anton Moldovan "Building an efficient replication system for thousands of ter...
 
Kamailio with Docker and Kubernetes
Kamailio with Docker and KubernetesKamailio with Docker and Kubernetes
Kamailio with Docker and Kubernetes
 

Recently uploaded

KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 

Recently uploaded (20)

KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 

Lindsay distributed geventzmq

  • 1. Distributed Systems with ZeroMQ and gevent Jeff Lindsay @progrium
  • 2. Why distributed systems? Harness more CPUs and resources Run faster in parallel Tolerance of individual failures Better separation of concerns
  • 3. Most web apps evolve into distributed systems
  • 11. Amazon AWS Provider Web Provider API Client Provider TwiML
  • 12. ZeroMQ + gevent Two powerful and misunderstood tools
  • 14. Distributed computing is just another flavor of local concurrency
  • 15. Multithreading Shared Memory Thread Thread Thread Distributed system Shared Database App App App
  • 16. Concurrency models Execution model Defines the “computational unit” Communication model Means of sharing and coordination
  • 17. Concurrency models Traditional multithreading OS threads Shared memory, locks, etc Async or Evented I/O I/O loop + callback chains Shared memory, futures Actor model Shared nothing “processes” Built-in messaging
  • 18. Examples Erlang Actor model Scala Actor model Go Channels, Goroutines Everything else (Ruby, Python, PHP, Perl, C/C++, Java) Threading Evented
  • 19. Erlang is special. Normally, the networking of distributed systems is tacked on to the local concurrency model. MQ, RPC, REST, ...
  • 20. Why not always use Erlang?
  • 21. Why not always use Erlang? Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Functional programming isn’t mainstream
  • 22. Why not always use Erlang? Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Functional programming isn’t mainstream Biggest reason It’s not always the right tool for the job
  • 23. Amazon AWS Provider Web Provider API Client Provider TwiML
  • 24. Service Oriented Architecture Multiple languages Heterogeneous cluster
  • 25. RPC
  • 28. RPC Client / server Mapping to functions Message serialization
  • 29. RPC Client / server Mapping to functions Message serialization Poor abstraction of what you really want
  • 30. What you want are tools to help you get distributed actor model concurrency like Erlang ... without Erlang. Even better if they're decoupled and optional.
  • 31. Rarely will you build an application as part of a distributed system that does not also need local concurrency.
  • 32. Communication model How do we unify communications in local concurrency and distributed systems across languages?
  • 33. Execution model How do we get Erlang-style local concurrency without interfering with the language's idiomatic paradigm?
  • 37. Misconceptions It’s just another MQ, right? Not really.
  • 38. Misconceptions It’s just another MQ, right? Not really.
  • 39. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right?
  • 40. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really.
  • 41. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really.
  • 42. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really. Wait, isn’t messaging a solved problem?
  • 43. Misconceptions It’s just another MQ, right? Not really. Oh, it’s just sockets, right? Not really. Wait, isn’t messaging a solved problem? *sigh* ... maybe.
  • 46. Regular Sockets Point to point Stream of bytes
  • 47. Regular Sockets Point to point Stream of bytes Buffering
  • 48. Regular Sockets Point to point Stream of bytes Buffering Standard API
  • 49. Regular Sockets Point to point Stream of bytes Buffering Standard API TCP/IP or UDP, IPC
  • 55. Messaging Messages are atomic Messages can be routed
  • 56. Messaging Messages are atomic Messages can be routed
  • 57. Messaging Messages are atomic Messages can be routed
  • 58. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 59. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 60. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 61. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 62. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 63. Messaging Messages are atomic Messages can be routed Messages may sit around
  • 64. Messaging Messages are atomic Messages can be routed Messages may sit around Messages are delivered
  • 65. Messaging Messages are atomic Messages can be routed Messages may sit around Messages are delivered
  • 66. Rise of the Big MQ
  • 67. App App Reliable Message Broker Persistent Queues App App
  • 68. App App App App
  • 69. AMQP MQ Producer Consumer
  • 70. AMQP MQ Binding Producer X Consumer Exchange Queue
  • 71. AMQP MQ Producer X Consumer Exchange Queue
  • 74. AMQP Recipes Work queues Publish/Subscribe Distributing tasks among workers Sending to many consumers at once X
  • 75. AMQP Recipes Work queues Publish/Subscribe Distributing tasks among workers Sending to many consumers at once X Routing Receiving messages selectively foo X bar baz
  • 76. AMQP Recipes Work queues Publish/Subscribe Distributing tasks among workers Sending to many consumers at once X Routing RPC Receiving messages selectively Remote procedure call implementation foo X bar baz
  • 77. Drawbacks of Big MQ Lots of complexity Queues are heavyweight HA is a challenge Poor primitives
  • 78. Enter ZeroMQ “Float like a butterfly, sting like a bee”
  • 79. Echo in Python Server Client 1 import zmq 1 import zmq 2 context = zmq.Context() 2 context = zmq.Context() 3 socket = context.socket(zmq.REP) 3 socket = context.socket(zmq.REQ) 4 socket.bind("tcp://127.0.0.1:5000") 4 socket.connect("tcp://127.0.0.1:5000") 5 5 6 while True: 6 for i in range(10): 7 msg = socket.recv() 7 msg = "msg %s" % i 8 print "Received", msg 8 socket.send(msg) 9 socket.send(msg) 9 print "Sending", msg 10 reply = socket.recv()
  • 80. Echo in Ruby Server Client 1 require "zmq" 1 require "zmq" 2 context = ZMQ::Context.new(1) 2 context = ZMQ::Context.new(1) 3 socket = context.socket(ZMQ::REP) 3 socket = context.socket(ZMQ::REQ) 4 socket.bind("tcp://127.0.0.1:5000") 4 socket.connect("tcp://127.0.0.1:5000") 5 5 6 loop do 6 (0...10).each do |i| 7 msg = socket.recv 7 msg = "msg #{i}" 8 puts "Received #{msg}" 8 socket.send(msg) 9 socket.send(msg) 9 puts "Sending #{msg}" 10 end 10 reply = socket.recv 11 end
  • 81. Echo in PHP Server Client 1 <?php 1 <?php 2 $context = new ZMQContext(); 2 $context = new ZMQContext(); 3 $socket = $context->getSocket(ZMQ::SOCKET_REP); 3 $socket = $context->getSocket(ZMQ::SOCKET_REQ); 4 $socket->bind("tcp://127.0.0.1:5000"); 4 $socket->connect("tcp://127.0.0.1:5000"); 5 5 6 while (true) { 6 foreach (range(0, 9) as $i) { 7 $msg = $socket->recv(); 7 $msg = "msg {$i}"; 8 echo "Received {$msg}"; 8 $socket->send($msg); 9 $socket->send($msg); 9 echo "Sending {$msg}"; 10 } 10 $reply = $socket->recv(); 11 ?> 11 } 12 ?>
  • 82. Bindings ActionScript, Ada, Bash, Basic, C, Chicken Scheme, Common Lisp, C#, C++, D, Erlang, F#, Go, Guile, Haskell, Haxe, Java, JavaScript, Lua, Node.js, Objective-C, Objective Caml, ooc, Perl, PHP, Python, Racket, REBOL, Red, Ruby, Smalltalk
  • 89. Plumbing inproc ipc tcp multicast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  • 90. Plumbing inproc ipc tcp multicast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  • 91. Plumbing inproc ipc tcp multicast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  • 98. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB
  • 99. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 100. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 101. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 102. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) PULL PUSH PULL PULL
  • 103. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUB Push-Pull (Pipelining) Pair PULL PULL PAIR PAIR PUSH PULL
  • 104. Devices Queue Forwarder Streamer Design architectures around devices.
  • 105. Devices Queue Forwarder Streamer REQ REP Design architectures around devices.
  • 106. Devices Queue Forwarder Streamer PUB SUB Design architectures around devices.
  • 107. Devices Queue Forwarder Streamer PUSH PULL Design architectures around devices.
  • 109. Performance Orders of magnitude faster than most MQs
  • 110. Performance Orders of magnitude faster than most MQs Higher throughput than raw sockets
  • 111. Performance Orders of magnitude faster than most MQs Higher throughput than raw sockets Intelligent message batching
  • 112. Performance Orders of magnitude faster than most MQs Higher throughput than raw sockets Intelligent message batching Edge case optimizations
  • 113. Concurrency? "Come for the messaging, stay for the easy concurrency"
  • 114. Hintjens’ Law of Concurrency e= mc 2 E is effort, the pain that it takes M is mass, the size of the code C is conflict, when C threads collide
  • 115. Hintjens’ Law of Concurrency
  • 116. Hintjens’ Law of Concurrency
  • 117. Hintjens’ Law of Concurrency ZeroMQ: e=mc 2, for c=1
  • 118. ZeroMQ Easy ... familiar socket API Cheap ... lightweight queues in a library Fast ... higher throughput than raw TCP Expressive ... maps to your architecture Messaging toolkit for concurrency and distributed systems.
  • 120. Threading vs Evented Evented seems to be preferred for scalable I/O applications
  • 121. Evented Stack Non-blocking Code Flow Control I/O Abstraction Reactor I/O Loop Event Poller
  • 122. 1 def lookup(country, search_term): 2 main_d = defer.Deferred() 3 4 def first_step(): 5 query = "http://www.google.%s/search?q=%s" % (country,search_term) 6 d = getPage(query) 7 d.addCallback(second_step, country) 8 d.addErrback(failure, country) 9 10 def second_step(content, country): 11 m = re.search('<div id="?res.*?href="(?P<url>http://[^"]+)"', 12 content, re.DOTALL) 13 if not m: 14 main_d.callback(None) 15 return 16 url = m.group('url') 17 d = getPage(url) 18 d.addCallback(third_step, country, url) 19 d.addErrback(failure, country) 20 21 def third_step(content, country, url): 22 m = re.search("<title>(.*?)</title>", content) 23 if m: 24 title = m.group(1) 25 main_d.callback(dict(url = url, title = title)) 26 else: 27 main_d.callback(dict(url=url, title="{not-specified}")) 28 29 def failure(e, country): 30 print ".%s FAILED: %s" % (country, str(e)) 31 main_d.callback(None) 32 33 first_step() 34 return main_d
  • 123. gevent “Regular” Python Greenlets Monkey patching Reactor / Event Poller
  • 124. Green threads “Threads” implemented in user space (VM, library)
  • 125. Monkey patching socket, ssl, threading, time
  • 129. Performance http://nichol.as
  • 130. Performance http://nichol.as
  • 131. Performance http://nichol.as
  • 132. Building a Networking App 1 #=== 2 # 1. Basic gevent TCP server 3 4 from gevent.server import StreamServer 5 6 def handle_tcp(socket, address): 7 print 'new tcp connection!' 8 while True: 9 socket.send('hellon') 10 gevent.sleep(1) 11 12 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 13 tcp_server.serve_forever()
  • 133. 1 #=== 2 # 2. Basic gevent TCP server and WSGI server 3 4 from gevent.pywsgi import WSGIServer 5 from gevent.server import StreamServer 6 7 def handle_http(env, start_response): 8 start_response('200 OK', [('Content-Type', 'text/html')]) 9 print 'new http request!' 10 return ["hello world"] 11 12 def handle_tcp(socket, address): 13 print 'new tcp connection!' 14 while True: 15 socket.send('hellon') 16 gevent.sleep(1) 17 18 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 19 tcp_server.start() 20 21 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 22 http_server.serve_forever()
  • 134. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 print 'new http request!' 8 return ["hello world"] 9 10 def handle_tcp(socket, address): 11 print 'new tcp connection!' 12 while True: 13 socket.send('hellon') 14 gevent.sleep(1) 15 16 def client_connect(address): 17 sockfile = create_connection(address).makefile() 18 while True: 19 line = sockfile.readline() # returns None on EOF 20 if line is not None: 21 print "<<<", line, 22 else: 23 break 24 25 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 26 tcp_server.start() 27 28 gevent.spawn(client_connect, ('127.0.0.1', 1234)) 29 30 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 31 http_server.serve_forever()
  • 135. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 print 'new http request!' 8 return ["hello world"] 9 10 def handle_tcp(socket, address): 11 print 'new tcp connection!' 12 while True: 13 socket.send('hellon') 14 gevent.sleep(1) 15 16 def client_connect(address): 17 sockfile = create_connection(address).makefile() 18 while True: 19 line = sockfile.readline() # returns None on EOF 20 if line is not None: 21 print "<<<", line, 22 else: 23 break 24 25 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 26 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 27 greenlets = [ 28 gevent.spawn(tcp_server.serve_forever), 29 gevent.spawn(http_server.serve_forever), 30 gevent.spawn(client_connect, ('127.0.0.1', 1234)), 31 ] 32 gevent.joinall(greenlets)
  • 138. 1 from gevent import spawn 2 from gevent_zeromq import zmq 3 4 context = zmq.Context() 5 6 def serve(): 7 socket = context.socket(zmq.REP) 8 socket.bind("tcp://localhost:5559") 9 while True: 10 message = socket.recv() 11 print "Received request: ", message 12 socket.send("World") 13 14 server = spawn(serve) 15 16 def client(): 17 socket = context.socket(zmq.REQ) 18 socket.connect("tcp://localhost:5559") 19 for request in range(10): 20 socket.send("Hello") 21 message = socket.recv() 22 print "Received reply ", request, "[", message, "]" 23 24 spawn(client).join()
  • 139. Actor model? Easy to implement, in whole or in part, optionally with ZeroMQ
  • 141. What is gevent missing?
  • 142. What is gevent missing? Documentation
  • 143. What is gevent missing? Documentation Application framework
  • 145. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 print 'new http request!' 8 return ["hello world"] 9 10 def handle_tcp(socket, address): 11 print 'new tcp connection!' 12 while True: 13 socket.send('hellon') 14 gevent.sleep(1) 15 16 def client_connect(address): 17 sockfile = create_connection(address).makefile() 18 while True: 19 line = sockfile.readline() # returns None on EOF 20 if line is not None: 21 print "<<<", line, 22 else: 23 break 24 25 tcp_server = StreamServer(('127.0.0.1', 1234), handle_tcp) 26 http_server = WSGIServer(('127.0.0.1', 8080), handle_http) 27 greenlets = [ 28 gevent.spawn(tcp_server.serve_forever), 29 gevent.spawn(http_server.serve_forever), 30 gevent.spawn(client_connect, ('127.0.0.1', 1234)), 31 ] 32 gevent.joinall(greenlets)
  • 146. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 from gservice.core import Service 6 7 def handle_http(env, start_response): 8 start_response('200 OK', [('Content-Type', 'text/html')]) 9 print 'new http request!' 10 return ["hello world"] 11 12 def handle_tcp(socket, address): 13 print 'new tcp connection!' 14 while True: 15 socket.send('hellon') 16 gevent.sleep(1) 17 18 def client_connect(address): 19 sockfile = create_connection(address).makefile() 20 while True: 21 line = sockfile.readline() # returns None on EOF 22 if line is not None: 23 print "<<<", line, 24 else: 25 break 26 27 app = Service() 28 app.add_service(StreamServer(('127.0.0.1', 1234), handle_tcp)) 29 app.add_service(WSGIServer(('127.0.0.1', 8080), handle_http)) 30 app.add_service(TcpClient(('127.0.0.1', 1234), client_connect)) 31 app.serve_forever()
  • 147. 1 from gservice.core import Service 2 from gservice.config import Setting 3 4 class MyApplication(Service): 5 http_port = Setting('http_port') 6 tcp_port = Setting('tcp_port') 7 connect_address = Setting('connect_address') 8 9 def __init__(self): 10 self.add_service(WSGIServer(('127.0.0.1', self.http_port), self.handle_http)) 11 self.add_service(StreamServer(('127.0.0.1', self.tcp_port), self.handle_tcp)) 12 self.add_service(TcpClient(self.connect_address, self.client_connect)) 13 14 def client_connect(self, address): 15 sockfile = create_connection(address).makefile() 16 while True: 17 line = sockfile.readline() # returns None on EOF 18 if line is not None: 19 print "<<<", line, 20 else: 21 break 22 23 def handle_tcp(self, socket, address): 24 print 'new tcp connection!' 25 while True: 26 socket.send('hellon') 27 gevent.sleep(1) 28 29 def handle_http(self, env, start_response): 30 start_response('200 OK', [('Content-Type', 'text/html')]) 31 print 'new http request!' 32 return ["hello world"]
  • 148. 1 # example.conf.py 2 3 pidfile = 'example.pid' 4 logfile = 'example.log' 5 http_port = 8080 6 tcp_port = 1234 7 connect_address = ('127.0.0.1', 1234) 8 9 def service(): 10 from example import MyApplication 11 return MyApplication() # Run in the foreground gservice -C example.conf.py # Start service as daemon gservice -C example.conf.py start # Control service gservice -C example.conf.py restart gservice -C example.conf.py reload gservice -C example.conf.py stop # Run with overriding configuration gservice -C example.conf.py -X 'http_port = 7070'
  • 149. Generalizing gevent proves a model that can be implemented in almost any language that can implement an evented stack
  • 150. gevent Easy ... just normal Python Small ... only 25 modules Fast ... top performing server Compatible ... works with most libraries Futuristic evented platform for network applications.
  • 151. Raiden Lightning fast, scalable messaging https://github.com/progrium/raiden
  • 153. Conclusion Two very simple, but very powerful tools for distributed / concurrent systems