asyncio是遵循Python标准库的一个异步 I/O框架.在这篇文章里,我将介绍 uvloop:
可以完整替代asyncio事件循环.uvloop是用Cython写的,基于 libuv.
uvloop 使得 asyncio 更快. 实际上,比nodejs,gevent,以及其他任何Python异步框架至少快两倍 .uvloop
asyncio 基于性能的测试接近于Go程序.
asyncio 模块, 是在 PEP 3156引入的, 是一个集合,包含网络传输, 协议, 和抽象的流, 带有可插拔的事件循环.
事件循环是asyncio的核心.它提供如下API:
-
调用方法的调度
-
通过网络传输数据
-
执行 DNS 查询,
-
处理 OS 操作系统信号
-
对创建服务器和连接进行封装
-
子进程异步处理
目前 uvloop 只支持 *nix 平台和 Python 3.5。
uvloop 是 Python 内建的 asyncio 事件循环的替代品,你可以通过 pip 来安装:
$ pip install uvloop
在你的 asyncio 代码中使用 uvloop 非常简单:
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
上面的代码片段让 asyncio.get_event_loop() 返回一个 uvloop 的实例。
你还可以显式的创建一个uvloop实例,通过调用uvloop.new_event_loop()。
uvloop是用Cython编写的,并建立在libuv之上。
libuv是一种高性能的、跨平台异步的 I/O
类库,nodejs也使用到了它。由于nodejs是如此的广泛和流行,可以知道libuv是快速且稳定的。
uvloop 实现了所有的asyncio 事件循环APIs。高级别的Python对象包装了低级别的libuv 结构体和函数方法。
继承可以使得代码保持DRY(不要重复自己),并确保任何手动的内存管理都可以与libuv的原生类型的生命周期保持同步。
与其它实现相比,为了检测uvloop栈性能,我们创建了toolbench基准测试,用于标准的TCP和UNIX套接字I/O,和HTTP协议性能的基准
。
基准测试服务器运行在一个包含外部负载生成工具 (wrk HTTP 基准测试)的Docker容器内,它测试请求吞吐量与延迟。
这篇博客中所有的基准测试都运行于Intel Xeon CPU E5-1620 v2 @ 3.70GHz的 Ubuntu
Linux系统.我们使用的是Python 3.5,所有服务器都是单核. 此外,Go代码中使用了GOMAXPROCS=1
,nodejs没有使用集群,并且所有的Python服务器都是单线程.每一个基准测试集都设置了TCP_NODELAY标识。
在Mac OS X上的基准报告结果也很相似。
这个基准测试使用不同的消息数目对一个简单的回显服务器的性能进行了测试。我们分别使用了1, 10, 和100 KiB
的包。并发级别是10。每一个基准运行了30秒。
可以点击这里查看完整的TCP基准报告。
每个位置的一些意见:
-
asyncio-streams。 asyncio
和其内置的纯Python实现的事件循环。在这个基准测试中,我们测试了高级别的流的抽象的性能。我们使用asyncio.create_server()来创建一个服务器,把一对(reader,
writer) 传递给客户端协同程序.
-
tornado。 这个服务器实现了一个非常简单的Tornado 协议,它能够把收到的消息立即回复回去。
-
curio-streams。 Curio是Python aio 库上的新成员。
与asyncio-streams类似,在这个基准测试中,我们测试了curio 流,使用curio.make_streams()来创建了一对(reader,
writer),它提供了一些高级的API,如readline()。
-
twisted。 跟Tornado类似,我们测试了一个最小的回声协议。
-
curio。这个基准测试测试了curio 套接字的性能:这是一个实现了sock.recv() 和 sock.sendall()紧密循环的协同程序。
-
uvloop-streams。就如在#2中提到的,这里我们测试了asyncio高级流的性能,只不过这此时基于uvloop。
-
gevent。在一个紧密循环里通过使用gevent.StreamServer和一个gevent套接字发送接受数据。
-
asyncio。看起来普通的asyncio非常的快速!跟第2和4点类似,我们测试了一个最小的回声协议,它是使用纯Python的asyncio所实现的。
-
nodejs。我们使用net.createServer API 在nodejs v4.2.6里测试流的性能。
-
uvloop。这个基准测试测试了一个最小的回声协议(就如 #2, #4, #8),它是使用基于uvloop的asyncio实现的。 使用1
KiB消息的情况下,uvloop是最快的实现,可以高达每秒钟105,000的请求!使用100 KiB消息的情况下, uvloop的速度可以达到大概2.3
GiB/s。
-
Go。一个 net.Conn.Read/Write 调用的紧密循环。 Golang 性能跟uvloop非常接近,在10 和100
KiB消息情况下会稍微好一些。
所有的基准测试的代码可以在这里找到。
也可以查看所有的UNIX套接字基准测试结果。
最初,我们想要在asyncio和uvloop上针对nodejs和Go进行测试。aiohttp是使用asyncio编写异步HTTP服务器和客户端
最流行的框架。
也可以查看完整的HTTP基准测试报告。
然而,aiohttp 上的性能瓶颈确实其HTTP解析器,它比较慢,因此即使使用的I/O类库再快也没什么卵用。为了让事情更有趣,我们为
http-parser (nodejs的 HTTP 解析器C类库,最初是为Nginx研发的)
创建了一个Python绑定(binding)。这个类库被命名为httptools,并且在Github和PyPI都可以找到。
对于HTTP,所有的基准使用wrk 来生成负载。 并发级别设置为300。每个基准的持续时间为30秒。
令人惊奇的是,纯Python实现的asyncio在高性能的HTTP解析器的帮助下,比使用同样HTTP解析器的nodejs表现的快很多!
Go在1 KiB响应情况下要更快些,但是uvloop和asyncio的组合却在10/100
KiB响应情况下要快很多。使用httptools的asyncio和uvloop的服务质量非常棒,对于Go来说也一样。
不可否认,基于httptools的服务器非常的小巧,而且不像其他实现那样不包含任何路由逻辑。尽管如此,这个基准却演示了uvloop和一个高效实现的协议配合能变得多么快速。
我们可以得出结论, 利用uvloop可以写出在单CPU内核下每秒钟能够发出上万个请求的Python网络代码。
在多内核系统下,可以使用进程池来进一步来改善系统性能。
uvloop 和 asyncio,在加上Python 3.5里
async/await的强大能力,使得使用Python编写高性能的网络代码更容易了。
请试用下uvloop (github) 并分享下使用结果吧!
End
为了让大家能有更多的好文章可以阅读,36大数据联合华章图书共同推出「祈文奖励计划」,该计划将奖励每个月对大数据行业贡献(翻译or投稿)最多的用户中选出最前面的10名小伙伴,统一送出华章图书邮递最新计算机图书一本。投稿邮箱:[email protected]
点击查看:你投稿,我送书,「祈文奖励计划」活动详情>>>
如果有人质疑大数据?不妨把这两个视频转给他
视频:大数据到底是什么 都说干大数据挣钱 1分钟告诉你都在干什么
人人都需要知道 关于大数据最常见的10个问题
从底层到应用,那些数据人的必备技能
如何高效地学好 R?
一个程序员怎样才算精通Python?
排名前50的开源Web爬虫用于数据挖掘
33款可用来抓数据的开源爬虫软件工具
在中国我们如何收集数据?全球数据收集大教程
PPT:数据可视化,到底该用什么软件来展示数据?
干货|电信运营商数据价值跨行业运营的现状与思考
大数据分析的集中化之路 建设银行大数据应用实践PPT
【实战PPT】看工商银行如何利用大数据洞察客户心声?
六步,让你用Excel做出强大漂亮的数据地图
数据商业的崛起 解密中国大数据第一股——国双
双11剁手幕后的阿里“黑科技” OceanBase/金融云架构/ODPS/dataV
金融行业大数据用户画像实践
“
讲述大数据在金融、电信、工业、商业、电子商务、网络游戏、移动互联网等多个领域的应用,以中立、客观、专业、可信赖的态度,多层次、多维度地影响着最广泛的大数据人群
搜索「36大数据」或输入36dsj.com查看更多内容。
投稿/商务/合作:[email protected]