The Many Faces of Concurrency in Python

32
Paradigms and tools for building high-performing systems The Many Faces of Concurrency in Python Sagiv Malihi [email protected] @sagiv

Transcript of The Many Faces of Concurrency in Python

Page 1: The Many Faces of Concurrency in Python

Paradigms and tools for building high-performing systemsThe Many Faces of Concurrency in Python

Sagiv [email protected] @sagiv

Page 2: The Many Faces of Concurrency in Python

2© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Who Am I?

Page 3: The Many Faces of Concurrency in Python

3© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• Sagiv Malihi• SW Architect – SON Group• @sagiv• smalihi at cisco

Page 4: The Many Faces of Concurrency in Python

4© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

What are We Building?

Page 5: The Many Faces of Concurrency in Python

5© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• Connect to all antennas to constantly make adjustments

• Read & analyze tons of statistics• Synchronize several physical

locations

Self Optimizing (cellular) Networks

Page 6: The Many Faces of Concurrency in Python

6© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• Pelephone as 1st customer• followed by AT&T (!)• now already in tens of operators

the system had to grow

Page 7: The Many Faces of Concurrency in Python

7© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

We Needed to Scale!

Page 8: The Many Faces of Concurrency in Python

8© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Concurrency vs.

Parallelism vs.

Distributed System

Page 9: The Many Faces of Concurrency in Python

Concurrency – running multiple tasks in overlapping time

periods

Page 10: The Many Faces of Concurrency in Python

Parallelism – when multiple tasks actually take place at

the same time (e.g. on separate cores)

Page 11: The Many Faces of Concurrency in Python

Distributed Systems – execute tasks in parallel over

several machines (in different locations)

Page 12: The Many Faces of Concurrency in Python

12© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Concurrency

Page 13: The Many Faces of Concurrency in Python

Connecting to thousands of cell towers

Continuously tweaking tilt, coverage, handovers…

Page 14: The Many Faces of Concurrency in Python

14© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• shared mem + switching = races• the GIL prevents true parallelism• threads are resource-intensive

threading is not a good choice

Page 15: The Many Faces of Concurrency in Python

15© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• using threads is easy• IO is still concurrent• c extensions can release the GIL• IronPython / Jython are GIL-less

threading does have an upside

Page 16: The Many Faces of Concurrency in Python

16© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• Predictable• Lightweight• Many libraries (incl. asyncio in stdlib)

coroutines to the rescue!

Page 17: The Many Faces of Concurrency in Python

17© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

def task1(): s = socket(...) while True: yield socket print socket.read()

def task2(): i = 1 while True: yield Sleep(1) print i i += 1

the basic idea is simpledef eventloop(*tasks): tasks = {task.next(): task for task in tasks} while True: sockets, sleeps =

filter_tasks(tasks) ready = select(sockets,

min(sleeps)) tasks = call_task_next(tasks,

ready)

eventloop(task1(), task2())

Page 18: The Many Faces of Concurrency in Python

18© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

import asyncioasync def slow_func(): await asyncio.sleep(1) return “answer”async def failed_func(): await asyncio.sleep(1) raise Exception(...)

python 3.5 async/await apiasync def test(): response = slow_func() try: await failed_func() except Exception as e:

print(e, await response)

loop = asyncio.get_event_loop()loop.run_until_complete(test())

Page 19: The Many Faces of Concurrency in Python

19© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

from gevent import monkey

monkey.patch_all()

gevent’s magic is a good tradeoff

Page 20: The Many Faces of Concurrency in Python

20© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Parallelism

Page 21: The Many Faces of Concurrency in Python

Hundreds of GB of binary logs & statistic files

are being parsed & processed every minute

Page 22: The Many Faces of Concurrency in Python

22© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

from multiprocessing import Process, Pipe

def f(conn): conn.send(“hello world”) conn.close()

multiprocessing is like magic!parent_conn, child_conn = Pipe()

p = Process(target=f, args=(child_conn,))

p.start()print(parent_conn.recv())

Page 23: The Many Faces of Concurrency in Python

23© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• multiprocessing fork()’s• does not play well with gevent• or threads• or large datasets in memory• but fixed in python 3.4 !

magic is not always a good thing

Page 24: The Many Faces of Concurrency in Python

24© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

from slaveprocess // uses subprocess + RPyC import run_in_process

def f(): return (“hello world”)print (run_in_process(f))

using subprocess is easier

Page 25: The Many Faces of Concurrency in Python

25© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Distributed Systems

Page 26: The Many Faces of Concurrency in Python

Almost 200 servers

in 10 physical locations

working as a unified cluster

Page 27: The Many Faces of Concurrency in Python

27© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• keeps a single-point-of-truth• on all servers• can act as a communications channel• we used mongodb

distributed DB can really help

Page 28: The Many Faces of Concurrency in Python

28© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• locks generally lead to deadlocks • optimistic transaction model• nodes change the ‘network image’• verifying consistency before ‘commit’

try to avoid locking

Page 29: The Many Faces of Concurrency in Python

29© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Summary

Page 30: The Many Faces of Concurrency in Python

30© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

• IO bound apps - • avoid threads, consider gevent• or asyncio

• CPU bound apps -• subprocess + RPyC

• distributed apps - • let a DB do the hard work

Page 31: The Many Faces of Concurrency in Python

31© 2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential

Thank You!

Questions?

Page 32: The Many Faces of Concurrency in Python