SlideShare une entreprise Scribd logo
1  sur  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
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?
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
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

Contenu connexe

Tendances

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
 

Tendances (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
 

Similaire à 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
 
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]Chris Suszyński
 
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
 
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdfOf the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdfanuradhasilks
 
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
 

Similaire à 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
 
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
You need Event Mesh, not Service Mesh - Chris Suszynski [WJUG 301]
 
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
 
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdfOf the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
Of the variedtypes of IPC, sockets arout and awaythe foremostcommon..pdf
 
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
 

Dernier

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 

Dernier (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 

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
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 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)
  • 137.
  • 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
  • 140.
  • 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