1. Scaling Django with Gevent Mahendra M @mahendra https://github.com/mahendra
2. @mahendra● Python developer for 6 years● FOSS enthusiast/volunteer for 14 years ● Bangalore LUG and Infosys LUG ● FOSS.in and LinuxBangalore/200x● Gevent user for 1 year● Twisted user for 5 years (before migrating) ● Added twisted support libraries like mustaine
7. Event driven web server request open(fp) reg() opened parse() event_loop() read_sql() reg()sql_read wri_sql() reg()sql_writ sock_wr() reg()responded close()
8. Two years back● Using python twisted for half of our products● Using django for the other half● Quite a nightmare
9. Python twisted● An event driven library (very scalable)● Using epoll or kqueue Server 1 Server 2 Nginx Client (SSL & LB) . . . Server N Proc 1 (:8080) Proc 2 (:8080) Proc N (:8080)
10. GeventA coroutine-based Python networking library thatuses greenlet to provide a high-level synchronousAPI on top of the libevent event loop.
11. GeventA coroutine-based Python networking library thatuses greenlet to provide a high-level synchronousAPI on top of the libevent event loop.
12. Coroutines● Python coroutines are almost similar to generators.def abc( seq ): lst = list( seq ) for i in lst: value = yield i if cmd is not None: lst.append( value )r = abc( [1,2,3] )r.send( 4 )
13. Gevent features● Fast event-loop based on libevent (epoll, kqueue etc.)● Lightweight execution units based on greenlets (coroutines)● Monkey patching support● Simple API● Fast WSGI server
14. Greenlets● Primitive notion of micro-threads with no implicit scheduling● Just co-routines or independent pseudo- threads● Other systems like gevent build micro-threads on top of greenlets.● Execution happens by switching execution among greenlet stacks● Greenlet switching is not implicit (switch())
17. How does gevent work● Creates an implicit event loop inside a dedicated greenlet● When a function in gevent wants to block, it switches to the greenlet of the event loop. This will schedule another child greenlet to run● The eventloop automatically picks up the fastest polling mechanism available in the system● One event loop runs inside a single OS thread (process)
18. Gevent codeimport geventfrom gevent import socketurls = [www.google.com, www.example.com,www.python.org]jobs = [gevent.spawn(socket.gethostbyname, url) forurl in urls]gevent.joinall(jobs, timeout=2)[job.value for job in jobs][220.127.116.11, 18.104.22.168, 22.214.171.124]
20. Gevent advantages● Almost synchronous code. No callbacks and deferreds● Lightweight greenlets● Good concurrency● No issues of python GIL● No need for in-process locking, since a greenlet cannot be pre-empted
21. Gevent issues● A greenlet will run till it blocks or switches ● Be vary of large/infinite loops● Monkey patching is required for un-supported blocking libraries. Might not work well with some libraries
22. Our django dream● We love django● I like twisted, but love django more ● Coding complexity ● Lack of developers for hire ● Deployment complexity● Gevent saved the day
23. The Django Problem● In a HTTP request cycle, we wanted the following operations ● Fetch some metadata for an item being sold ● Purchase the item for the user in the billing system ● Fetch ads to be shown along with the item ● Fetch recommendations based on this item● In parallel … !! ● Twisted was the only option
25. Twisted issues● The issues were with everything else ● Header management ● Templates for response ● ORM support ● SOAP, REST, Hessian/Burlap support – We liked to use suds, requests, mustaine etc. ● Session management and auth ● Caching support● The above are djangos strength ● Djangos vibrant eco-system (celery, south, tastypie)
26. gunicorn● A python WSGI HTTP server● Supports running code under worker, eventlet, gevent etc. ● Uses monkey patching● Excellent django support ● gunicorn_django app.settings● Enabled gevent support for our app by default without any code changes● Spawns and manages worker processes and distributes load amongst them
28. Migrating our products● Migrating our entire code base (2 products) took around 1 week to finish● Was easier because we were already using inlineCallbacks() decorator of twisted● Only small parts of our code had to be migrated
30. Life today● Single framework for all 4 products● Use djangos awesome features and ecosystem● Increased scalability. More so with celery.● Use blocking python libraries without worrying too much● No more usage of python-twisted● Coding, testing and maintenance is much easier● We are hiring!!