DEVNET-3627: Make Python applications faster with asyncio!

DEVNET-3627: Make Python applications faster with asyncio!

Have you ever needed to run some commands with Python across multiple network devices? Or may be you needed to call a slow API tens or hundreds of times and the script running time was approaching minutes or even hours? Are you curious how to achieve concurrency in Python? If you answered yes to any of these questions, then this session is for you!
This session will explain what concurrency is and what problems it solves. Advantages and disadvantages of main approaches to achieve concurrency in Python will be discussed. Python 3.5 built-in library asyncio will be introduced and some examples of use-cases for network engineers will be shown and explained.

E12e72ac0ff561a6f970e7f7af717cb0?s=128

Dmitry Figol

June 12, 2018
Tweet

Transcript

  1. #CLUS

  2. #CLUS Dmitry Figol, WW Enterprise Sales Systems Engineer - Programmability

    DEVNET-3627 Make Python applications faster with asyncio!
  3. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 About me @dmfigol dmfigol dmfigol.me dmfigol dmfigol
  4. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 • Is Python slow? • Concurrency and parallelism in Python: threads, multiple processes, async • High-level overview of asyncio library building blocks • asyncio examples in networking: asynchronous REST and SSH calls Agenda
  5. Is Python slow?

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

    Public #CLUS DEVNET-3627 Python speed • Everyone says Python is slow, but … • Is it really? • What is the bottleneck? • 95% it is not CPU, it is input/output (I/O) – database queries, network • If Python was fast, it wouldn’t really help Takeaway: Python is actually slow, but it does not matter
  7. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Python implementations There are different Python implementations: • CPython (default) • IronPython • PyPy – try this if you want faster Python! But this talk is about I/O
  8. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 I/O in Python - scenario • A network engineer just recently learned Python and how to interact with network devices using SSH or API • Needs to collect memory statistics and ARP table • One week of hacking and success! Working great for one device • ..but need to do the same for 1000 devices • Let’s add for loop and it should be fine… right? RIGHT??
  9. Demo – sequential SSH to network devices with netmiko

  10. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 I/O is what is really slow Especially multiplied by 100..10000 times
  11. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Introducing concurrency • Concurrency – doing multiple things at once • Typical approaches: • Threads • Multiple processes • Asynchronous programming (async)
  12. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Threading in Python • Running multiple threads (functions calls) at the same time • Shared state • Low overhead • Thread switching at random time by the scheduler • Global Interpreter Lock (GIL) – only one thread can run at the same time • Because of GIL, makes sense only for I/O heavy applications • Easy to add, hard to get right – shared state can cause racing conditions • Requires locks and queues to be safe, but most importantly experience
  13. Demo – SSH to network device with netmiko and threads

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

    Public #CLUS DEVNET-3627 Multiprocessing in Python • Spawns multiple Python interpreters as forks • Higher overhead than threads • Harder to communicate between processes • Higher memory footprint • Effective to distribute CPU heavy load across several cores
  15. Python asyncio

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

    Public #CLUS DEVNET-3627 Asynchronous programming • Intuition: when I am doing I/O and waiting for the response, I could do something else instead! • By default, runs a single thread and single process • Python 3.4 introduced new standard library: asyncio • Python 3.5 introduced new syntax: async/await • Completely different programming style which relies on Coroutines, Tasks and Event Loop
  17. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Coroutines predecessor - generators • Let’s discuss generators first • Generator is a function that produces a sequence of results instead of a single value • Uses yield statement • yield produces a value and suspends the function • Calling generator does not start running the function
  18. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Coroutines (pre-asyncio) • Bare yield is used • This allows the function to consume values • These functions are called coroutine functions • Objects returned by coroutine functions are called coroutines • Coroutines consume values • Generators produce values
  19. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Coroutines (asyncio) • Python 3.5 - new async/await syntax for asyncio coroutines • await is similar to bare yield – it expects values from I/O (e.g. HTTP response) • I/O places in the code are marked explicitly using await • await is used only in asyncio coroutines marked by async def • Usual functions can’t call async functions, only async functions can call async functions How to call async functions?
  20. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Task/Future (asyncio) • Future – an object that wraps coroutine • Returned immediately • Placeholder for the future result or exception • Can be cancelled if required • Task – subclass of Future • Has some extra methods to get the current stack • Has some differences how cancellation is handled compared to Future • The main primitive in asyncio world
  21. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Event loop (asyncio) • Event loop – is a loop that executes tasks • Different ways to mix tasks, schedule, start and stop them • Directly impacts the performance • Different loop implementations: • asyncio base loop – default • uvloop – speed increase x2-x4 • trio event loop • Other loops
  22. Demo – asynchronous SSH to network devices with netdev

  23. Demo – asynchronous HTTP using asyncio and aiohttp

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

    Public #CLUS DEVNET-3627 Real world use-case • Working on automated lab management system • Got 5 racks of gear, 100 devices, 700+ cables
  25. #CLUS © 2018 Cisco and/or its affiliates. All rights reserved.

    Cisco Public DEVNET-3627
  26. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Real world use-case (cont.) • 2 weeks for racking and stacking • Did we actually do cabling correctly? • Wrote a script to check that using CDP
  27. Demo – compare actual cabling from desired cabling using CDP

    output asynchronously
  28. Wrap-up

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

    Public #CLUS DEVNET-3627 Problems with asyncio • Documentation has room for improvement • Not many good learning resources available • API is not clean • Paradigm change • Not mature yet • Hard to migrate from existing codebase • Requires different library for any I/O operation: aiohttp (HTTP client), asyncssh and netdev (SSH), aiofiles (files read/write), etc.
  30. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Summary: Why use asyncio 1. Explicit control for task switching using await keyword 2. Less overhead and slightly faster than threads 3. Great scalability approach 4. Not hard for simple use-cases
  31. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Get Started with asyncio • Raymond Hettinger - Keynote on Concurrency - PyBay 2017 • Miguel Grinberg - Asynchronous Python for the Complete Beginner - PyCon 2017 • Łukasz Langa - Thinking In Coroutines - PyCon 2016 • Armin Ronacher – I don’t understand Python’s Asyncio • asyncio documentation • Nathaniel J Smith - Python Concurrency for Mere Mortals - Pyninsula #10 • Libraries: aiohttp, asyncssh, netdev
  32. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Code https://github.com/dmfigol/devnet-3627.git
  33. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Cisco Webex Teams Questions? Use Cisco Webex Teams (formerly Cisco Spark) to chat with the speaker after the session Find this session in the Cisco Events App Click “Join the Discussion” Install Webex Teams or go directly to the team space Enter messages/questions in the team space How Webex Teams will be moderated by the speaker until June 18, 2018. cs.co/ciscolivebot#DEVNET-3627 © 2018 Cisco and/or its affiliates. All rights reserved. Cisco Public 37 1 2 3 4
  34. Complete your online session evaluation © 2018 Cisco and/or its

    affiliates. All rights reserved. Cisco Public #CLUS Give us your feedback to be entered into a Daily Survey Drawing. Complete your session surveys through the Cisco Live mobile app or on www.CiscoLive.com/us. Don’t forget: Cisco Live sessions will be available for viewing on demand after the event at www.CiscoLive.com/Online. DEVNET-3627
  35. © 2018 Cisco and/or its affiliates. All rights reserved. Cisco

    Public #CLUS DEVNET-3627 Demos in the Cisco campus Walk-in self-paced labs Meet the engineer 1:1 meetings Related sessions Continue your education
  36. Thank you #CLUS

  37. #CLUS