魔术堆栈

uvloop:快速的Python网络连接

作者Yury Selivanov @ 1st1
2016年5月3日

TL; DR

asyncio是Python标准库附带的异步I / O框架。在此博客文章中,我们介绍uvloop:asyncio事件循环的完整替代品。uvloop用Cython编写,并建立在libuv之上

uvloop使asyncio更快。实际上,它至少比nodejs,gevent和任何其他Python异步框架快2倍。基于uvloop的asyncio的性能接近Go程序。

异步和uvloop

PEP 3156引入的asyncio模块是网络传输,协议和流抽象的集合,带有可插入事件循环。事件循环是异步的核心。它提供以下API:

  • 安排电话
  • 通过网络传输数据,
  • 执行DNS查询,
  • 处理操作系统信号,
  • 方便的抽象来创建服务器和连接,
  • 异步处理子流程。

目前,uvloop仅在* nix平台和Python 3.5上可用。

uvloop是内置asyncio事件循环的替代产品。您可以使用pip安装uvloop:

$ pip安装uvloop

在异步代码中使用uvloop很简单:

导入异步
导入 uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

上面的代码片段使任何asyncio.get_event_loop()调用都返回uvloop的实例。

您还可以通过调用显式创建uvloop实例 uvloop.new_event_loop()

建筑

uvloop用Cython编写,并建立在libuv之上。

libuv是供nodejs使用的高性能,多平台异步I / O库。由于nodejs的普及和流行,libuv既快速又稳定。

uvloop实现所有异步事件循环API。高级Python对象包装了低级libuv结构和函数。继承用于保持代码DRY并确保任何手动内存管理与libuv原语的寿命保持同步。

基准测试

为了检查uvloop的性能如何与其他实现相提并论,我们创建了一个工具台来对TCP和UNIX套接字I / O以及HTTP协议的性能进行基准测试。

标有基准的服务器在带有外部负载生成工具(HTTP基准的wrk)的Docker容器中运行,该工具可以测量请求的吞吐量和延迟。

本博客文章中的所有基准测试均在3.70GHz的Intel Xeon CPU E5-1620 v2和Ubuntu Linux上运行。我们使用Python 3.5,所有服务器均为单线程。另外,我们使用GOMAXPROCS=1Go代码,nodejs不使用集群,并且所有Python服务器都是单进程的。每个基准设置TCP_NODELAY标志。

Mac OS X上的基准测试结果非常相似。

TCP协议

此基准测试了具有不同消息大小的简单回显服务器的性能。我们使用1、10和100 KiB软件包。并发级别为10。每个基准测试运行30秒。

另请参阅完整的TCP基准报告
asynciotornadocuriotwistedcuriouvloopgeventasyncionodejsuvloopgolangstreamsstreamsstreams010,00020,00030,00040,00050,00060,00070,00080,00090,000100,000Requests / sec1 KiB10 KiB100 KiBasynciotornadocuriotwistedcuriouvloopgeventasyncionodejsuvloopgolangstreamsstreamsstreams0.00.20.40.60.81.01.21.41.61.82.02.22.4Latency (msec)1 KiB10 KiB100 KiB

关于每个职位的一些评论:

  1. ASYNCIO流。asyncio及其内置的纯Python事件循环。在此基准测试中,我们测试了高级流抽象的性能。我们asyncio.create_server()用来创建将一对传递(reader, writer)给客户端协程的服务器。
  2. 龙卷风。该服务器实现了一个非常简单的Tornado协议,该协议会立即将收到的所有数据发送回去。
  3. 古玩流。Curio是Python aio lib块上的新手。与asyncio-streams相似,在此基准测试中,我们测试curio流,curio.make_streams()用于创建一对(reader, writer)提供高级API(例如)的流readline()
  4. 扭曲。与龙卷风类似,这里我们测试最小回波协议。
  5. 古玩。此基准测试了古玩插槽的性能:sock.recv()sock.sendall()协程的紧密循环。
  6. uvloop流。与#2一样,这里我们测试asyncio高级流的性能,但是这次是在uvloop之上。
  7. gevent。我们使用gevent.StreamServergevent套接字在紧密的循环中发送/接收数据。
  8. ASYNCIO。看来,香草异步反应相当快!与#2和#4类似,这里我们测试在纯Python异步中实现的最小回显协议的性能。
  9. nodejs。我们使用net.createServerAPI在nodejs v4.2.6中测试流的性能。
  10. uvloop。此基准测试了在uvloop上以异步方式实现的最小回显协议(如#2,#4,#8)。有了1 KiB消息,uvloop是最快的实现,每秒高达105,000个请求!对于100 KiB消息,uvloop设法以大约2.3 GiB / s的速度运行。
  11. 围棋net.Conn.Read/Write通话紧密。Golang的性能与uvloop非常相似,对于10和100 KiB消息,性能稍好一些。

如何阅读箱形图: 99%75%50%25%min

所有基准的代码都可以在这里找到。

另请参见UNIX套接字基准测试结果

HTTP

最初,我们想针对nodejs和Go在asyncio和uvloop上测试aiohttp。aiohttp是使用asyncio编写异步HTTP服务器和客户端的最受欢迎的框架。

另请参阅完整的HTTP基准测试报告

但是,aiohttp的性能瓶颈竟然是其HTTP解析器,它是如此之慢,以至于底层I / O库的速度有多快都没有关系。为了使事情变得更有趣,我们为http-parser(最初为Nginx开发的nodejs HTTP解析器C库)创建了Python绑定。该库称为httptools,在Github和PyPI上可用。

对于HTTP,所有基准测试都使用wrk生成负载。并发级别设置为300。每个基准测试的持续时间为30秒。

asynciouvloopnodejsasynciogolanguvloopaiohttpaiohttphttptoolshttptools05,00010,00015,00020,00025,00030,00035,000Requests / sec1 KiB10 KiB100 KiBasynciouvloopnodejsasynciogolanguvloopaiohttpaiohttphttptoolshttptools0102030405060708090100110120Latency (msec)1 KiB10 KiB100 KiB14.63

出乎意料的是,借助高性能HTTP解析器,纯Python异步比使用相同HTTP解析器的nod​​ejs更快!

Go对于1 KiB响应更快,但是uvloop + asyncio对于10/100 KiB响应明显更好。服务质量对于使用httptools的asyncio和uvloop以及Go来说都是极好的。

诚然,与其他实现不同,基于httptools的服务器非常小,并且不包含任何路由逻辑。但是,该基准测试表明了使用有效实施的协议可以实现多快的uvloop。

结论

可以肯定地得出结论,使用uvloop,可以编写Python网络代码,每个CPU内核每秒可以推送成千上万的请求。在多核系统上,可以使用进程池进一步扩展性能。

uvloop和asyncio,再加上Python 3.5 中async / await的强大功能,使使用Python编写高性能网络代码比以往任何时候都更加容易。

请尝试uvloop(github)并与我们分享您的结果!

原文

提供更好的翻译建议

uvloop官网翻译的更多相关文章

  1. 卸载 Cloudera Manager 5.1.x.和 相关软件【官网翻译】

    问题导读: 1.不同的安装方式,卸载方法存在什么区别?2.不同的操作系统,卸载 Cloudera Manager Server and 数据库有什么区别? 重新安装不完整如果你来到这里,因为你的安装没 ...

  2. Knockoutjs官网翻译系列(一)

    最近马上要开始一个新项目的研发,作为第一次mvvm应用的尝试,我决定使用knockoutjs框架.作为学习的开始就从官网的Document翻译开始吧,这样会增加印象并加入自己的思考,说是翻译也并不是纯 ...

  3. 【官网翻译】性能篇(四)为电池寿命做优化——使用Battery Historian分析电源使用情况

    前言 本文翻译自“为电池寿命做优化”系列文档中的其中一篇,用于介绍如何使用Battery Historian分析电源使用情况. 中国版官网原文地址为:https://developer.android ...

  4. 【工利其器】必会工具之(三)systrace篇(1)官网翻译

    前言 Android 开发者官网中对systrace(Android System Trace)有专门的介绍,本篇文章作为systrace系列的开头,笔者先不做任何介绍,仅仅翻译一下官网的介绍.在后续 ...

  5. android測试工具MonkeyRunner--google官网翻译

    近期在复习之前的笔记,在回想MonkeyRunner时看了看google官网的内容,写得不错.就翻译出来分享下.事实上google官网真是一个学习的好地方. 基础知识 MonkeyRunner工具提供 ...

  6. Knockout 官网翻译

    Knockout 新版应用开发教程之创建view models与监控属性 章节导航 最近抽出点时间研究MVVM,包括司徒正美的avalon,google的angular,以及Knockout,博客园T ...

  7. Knockoutjs官网翻译系列(四) computed中依赖追踪是如何工作的

    初学者无需了解这些 ,但是很多高级程序员想知道我们为什么可以保持跟踪这些依赖以及可以正确的更新到UI中.它其实很简单.跟踪算法是这样的: 无论何时你定义了一个computed observable,K ...

  8. Knockoutjs官网翻译系列(三) 使用Computed Observables

    书接上回,前面谈到了在视图模型中可以定义普通的observable属性以及observableArray属性实现与UI元素的双向绑定,这一节我们继续探讨第三种可实现绑定的属性类型:computed o ...

  9. Linux Centos7 离线安装docker 【官网翻译和注释】

    Centos7的Docker安装 需要一个维护版本的centos7,所以6不行. 卸载旧版本 旧版本的docker被称为 docker or docker-engine 如果存在请删除它们. sudo ...

随机推荐

  1. JNDI 笔记

    原理:         在DataSource中事先建立多个数据库连接,保存在数据库连接池中.当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池 ...

  2. 常用css代码(scss mixin)

    溢出显示省略号 参过参数可以只是单/多行. /** * 溢出省略号 * @param {Number} 行数 */ @mixin ellipsis($rowCount: 1) { @if $rowCo ...

  3. FastJSON 远程执行漏洞,速速升级!

    相信大家用 FastJSON 的人应该不少,居然有漏洞,还不知道的赶紧往下看,已经知道此漏洞的请略过-- 2019年6月22日,阿里云云盾应急响应中心监测到FastJSON存在0day漏洞,攻击者可以 ...

  4. this关键字与super关键字区别

        this super 1 访问属性 访问本类中属性,如果本类中没有此属性,就从父类继承过来的属性中查找 (遵循就近原则) 访问父类中的属性 2 调用方法 访问本类中方法 直接访问父类中方法 3 ...

  5. BZOJ 4657 (网络流)

    题面 Nick最近在玩一款很好玩的游戏,游戏规则是这样的: 有一个n*m的地图,地图上的每一个位置要么是空地,要么是炮塔,要么是一些BETA狗,Nick需要操纵炮塔攻击BETA狗们. 攻击方法是:对于 ...

  6. HDU 6469 /// 二分

    题目大意: 分裂怪有1到n种等级, 第1级的分裂怪称为原子怪,它不会分裂,被击杀时会产生a[1]点经验: 而第k级的分裂怪死亡时则会分裂成a[k]个第k - 1级的分裂怪. 一个体力可以杀死一个怪物. ...

  7. spring-data-neo4j了解

    本项目demo地址[请阅读readme文件]: https://gitee.com/LiuDaiHua/project-neo4j 最近项目上要搭建一个关系图谱的东西,领导给了neo4j和d3两个概念 ...

  8. Neo4j百万级数据导入只需30s

    先上图:425万nodes.180万relationships只用了30s 243ms 项目需要生成关系图,开始考虑的是用Neo4j官网提供的REST API,从solr中查出2组数据先创建节点再创建 ...

  9. 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2  任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...

  10. python利用ConfigParser读写配置文件

    ConfigParser 是Python自带的模块, 用来读写配置文件, 用法非常简单. 配置文件的格式是: []包含的叫section,    section 下有option=value这样的键值 ...