Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Eventlet, ZeroMQ, and You
Search
Andrew Godwin
October 22, 2011
Programming
6
790
Eventlet, ZeroMQ, and You
A talk I gave at PyCon Ukraine 2011.
Andrew Godwin
October 22, 2011
Tweet
Share
More Decks by Andrew Godwin
See All by Andrew Godwin
Reconciling Everything
andrewgodwin
1
280
Django Through The Years
andrewgodwin
0
180
Writing Maintainable Software At Scale
andrewgodwin
0
420
A Newcomer's Guide To Airflow's Architecture
andrewgodwin
0
330
Async, Python, and the Future
andrewgodwin
2
630
How To Break Django: With Async
andrewgodwin
1
700
Taking Django's ORM Async
andrewgodwin
0
700
The Long Road To Asynchrony
andrewgodwin
0
620
The Scientist & The Engineer
andrewgodwin
1
730
Other Decks in Programming
See All in Programming
2025/3/18 サービスの成長で生じる幅広いパフォーマンスの問題を、 AIで手軽に解決する
shirahama_x
0
150
体得しよう!RSA暗号の原理と解読
laysakura
3
490
英語文法から学ぶ、クリーンな設計の秘訣
newnomad
1
260
CQRS+ES勉強会#1
rechellatek
0
380
RubyKaigiで手に入れた HHKB Studioのための HIDRawドライバ
iberianpig
0
170
プログラミング教育のコスパの話
superkinoko
0
110
フロントエンドテストの育て方
quramy
8
2.2k
SideKiqでジョブが二重起動した事象を深堀りしました
t_hatachi
0
170
リアクティブシステムの変遷から理解するalien-signals / Learning alien-signals from the evolution of reactive systems
yamanoku
1
210
Gunma.web #55
tinykitten
0
130
マルチアカウント環境での、そこまでがんばらない RI/SP 運用設計
wa6sn
0
220
アーキテクトと美学 / Architecture and Aesthetics
nrslib
12
2.9k
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
610
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
Automating Front-end Workflow
addyosmani
1369
200k
Speed Design
sergeychernyshev
28
850
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.7k
A Modern Web Designer's Workflow
chriscoyier
693
190k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
22
2.6k
A designer walks into a library…
pauljervisheath
205
24k
KATA
mclloyd
29
14k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.5k
Designing for Performance
lara
605
69k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.9k
Transcript
Eventlet, ZeroMQ & You Andrew Godwin @andrewgodwin
Who am I? http://www.flickr.com/photos/maistora/3014414972
The Plan http://www.flickr.com/photos/snapsi42/2609025344/
Eventlet Asynchronous concurrency framework http://www.flickr.com/photos/pagedooley/2814895287/
import eventlet from eventlet.green import urllib2 urls = ['http://ep.io', 'http://t.co']
results = [] def fetch(url): results.append(urllib2.urlopen(url).read()) for url in urls: eventlet.spawn(fetch, url)
Cooperative Threading You have to yield control. http://www.flickr.com/photos/nickwheeleroz/3406931272/
import eventlet import time def thread1(): time.sleep(5) # Does not
yield print 'five seconds a' eventlet.spawn(thread1) time.sleep(5) # Does not yield print 'five seconds b'
import eventlet import time def thread1(): eventlet.sleep(5) print 'five seconds
a' eventlet.spawn(thread1) eventlet.sleep(5) print 'five seconds b'
Greening the World It's that or monkeypatching. http://www.flickr.com/photos/mightyboybrian/3457507731/
import urllib2 from eventlet.green import urllib2 import zmq from eventlet.green
import zmq import socket from eventlet.green import socket
Nice Primitives Not to mention less race conditions. http://www.flickr.com/photos/mightyboybrian/3457507731/
from eventlet.timeout import Timeout try: with Timeout(30): do_stuff() except Timeout:
abort_abort()
from eventlet.semaphore import Semaphore sem = Semaphore(1) with sem: use_resource()
from eventlet.queue import Queue q = Queue() def worker(): while
True: print q.get() def producer(): while True: eventlet.sleep(1) q.put('lol') eventlet.spawn(worker) eventlet.spawn(producer)
from eventlet import GreenPool from eventlet.pools import Pool conns =
Pool(create=make_db_connection) threads = GreenPool(10) def querier(id): with pool.item() as conn: conn.execute('... WHERE id = %s', [id]) pool.imap(querier, [1, 2, 3, 4, 5])
Experiences from production There's still race conditions and bad libraries.
http://www.flickr.com/photos/iamdabe/4931554963/
Case Study: Epio Loadbalancer Now at version three. http://www.flickr.com/photos/jasohill/118616905/
Version One: HAProxy + reloader Occasionally slow, occasionally didn't reload.
Version Two: Custom Integrated Worked alright, but leaked sockets.
Version Three: Fresh, Separate Codenamed ”Mantrid”
address = ('0.0.0.0', 80) family = socket.AF_INET sock = eventlet.listen(address,
family) eventlet.serve( sock, self.handle, concurrency = 10000, )
address = ('127.0.0.1', 8042) family = socket.AF_INET sock = eventlet.listen(address,
family) management_app = ManagementApp(self) wsgi.server( sock, management_app.handle, )
class Spin(Action): def handle(self, sock, read_data, path, headers): while True:
# Sleep first eventlet.sleep(self.check_interval) # Check for another action action = self.balancer.resolve_host(self.host) if not isinstance(action, Spin): return action.handle( sock, read_data, path, headers )
ZeroMQ I was too lazy to use an Ø. http://www.flickr.com/photos/andresrueda/2926348197/
Not a message queue More like 'better sockets'. http://www.flickr.com/photos/96dpi/3816391053/
REQ / REP PUB / SUB PUSH / PULL
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.REQ)
sock.connect('tcp://127.0.0.1:1234') sock.connect('tcp://127.0.0.1:4321') sock.send('hi there') print sock.recv()
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.REP)
sock.bind('tcp://0.0.0.0:1234') while True: message = sock.recv() sock.send('you said: %s' % message)
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.PUB)
sock.connect('tcp://127.0.0.1:1234') sock.send('Hello, world!')
from eventlet.green import zmq ctx = zmq.Context() sock = ctx.socket(zmq.SUB)
sock.bind('tcp://0.0.0.0:1234') while True: print sock.recv()
The restrictions It's not quite too good to be true.
http://www.flickr.com/photos/maistora/3237164755/
Advanced ZeroMQ & Eventlet When one greenthread is not enough
http://www.flickr.com/photos/maistora/3237164755/
sock = ctx.socket(zmq.REQ) sock.send('help me! you're my only hope!') try:
with Timeout(30): response = sock.recv() deal_with(response) except Timeout: cleanup()
@zmq_loop(zmq.XREP, 8000) def handle_request(string): eventlet.sleep(10) return string * 2
try: parts = sock.recv_multipart(flags=zmq.NOBLOCK) except zmq.ZMQError, e: if e.errno ==
zmq.EAGAIN: eventlet.sleep(0.1) continue else: raise identities = parts[:parts.index("")] def call(identities, data): result = func(self, data) sock.send_multipart(identities + ["", result]) eventlet.spawn_n(call, identities, parts[-1])
Case Study: Epio Logging We really, really like data http://www.flickr.com/photos/jasohill/118616905/
Logging clients They're the things that make logs
Logging servers They're the things that save and store logs
# Servers zmq.PULL -> Recieves logs zmq.REP -> Lets website
query for log data # Clients zmq.PUSH -> Sends logs, connected to all servers
Conclusions Where Andrew waffles for a bit. http://www.flickr.com/photos/oimax/108058706/
Thanks. Andrew Godwin @andrewgodwin http://aeracode.org