大数据 爬虫Python AI SqlPythonPython 爬虫 web 数据分析 机器学习 人工智能

有没有一种编程语言可以每秒达到100万次请求?python!

2018-05-27  本文已影响31人  CoXie的大数据世界

很多公司正在从Python和其他编程语言中迁移出来,这样他们可以提高他们的操作性能并节省服务器的价格,但实际上并不需要。Python可以成为这项工作的正确工具。

Python社区最近在性能方面做了很多工作。CPython 3.6通过新的字典实现提高了整体解释器的性能。由于引入了更快的调用约定和字典查找缓存,CPython 3.7将会更快。

对于数字处理任务,您可以使用PyPy及其即时代码编译。你也可以运行NumPy的测试套件,它现在已经改进了与C扩展的整体兼容性。预计今年晚些时候PyPy将达到Python 3.5的一致性。

所有这些伟大的工作激励我在Python广泛使用的领域之一 - 网络和微服务开发领域进行创新。

进入Japronto!

Japronto是一款全新的微型框架,专为满足您的微服务需求而量身定制。其主要目标包括快速,可扩展和轻量级。借助asyncio,它可以让您同时进行同步编程和异步编程。它无耻地快速。甚至比NodeJS和Go还要快。

Japronto:https://github.com/squeaky-pl/japronto

Python微框架(蓝色),黑暗力量(绿色)和Japronto(紫色)

勘误表:正如用户@heppu指出的那样,Go的stdlib HTTP服务器的速度比图中显示的要快12%。还有一个非常棒的fasthttp服务器,在这个特定的基准测试中显然比Japronto 慢18%。真棒!详情请参阅httpsgithub.comsqueaky-pljaprontopull12和httpsgithub.comsqueaky-pljaprontopull14。

我们还可以看到,Meinheld WSGI服务器几乎与NodeJS和Go类似。尽管它有固有的阻塞设计,但与前面四个是异步Python解决方案相比,它是一个出色的表现者。所以不要相信任何人说异步系统总是更快。它们几乎总是更加并发,但除此之外还有更多。

我使用“Hello world!”应用程序来执行此微型基准测试,但它清楚地表明了许多解决方案的服务器框架开销。

这些结果是在具有8个VCPU的AWS c4.2xlarge实例上获得的,这些实例在圣保罗地区启动,采用默认共享租赁和HVM虚拟化和磁性存储。该机器运行的是Linux 4.4.0-53-通用x86_64内核的Ubuntu 16.04.1 LTS(Xenial Xerus)。该操作系统报告Xeon®CPU E5-2666 v3 @ 2.90GHz CPU。我使用了Python 3.6,我从源代码中全新编译。

公平地说,所有参赛者(包括Go)都运行单一工作流程。服务器使用wrk进行负载测试,每个连接使用1个线程,100个连接和24个同时(流水线)请求(2400个请求的累积并行度)。

HTTP流水线(图片信用维基百科)

HTTP流水线在这里至关重要,因为它是Japronto在执行请求时考虑的优化之一。

大多数服务器以与非流水客户端相同的方式执行流水线客户端的请求。他们不试图优化它。(事实上,Sanic和Meinheld也会默默地放弃来自流水线客户端的请求,这违反了HTTP 1.1协议。)

简而言之,流水线技术是客户端在通过相同TCP连接发送后续请求之前不需要等待响应的技术。为了确保通信的完整性,服务器以相同的顺序发回几个响应请求。

我将本篇博文的代码都已经打包放在我的群里啦。
如果需要代码或者需要有关python的资料都可以加。四九一,三零八,六五九,备注跨界,我就明白是你了

优化的细节

当许多小的GET请求被客户端一起流水线化时,它们很可能会在服务器端到达一个TCP数据包(感谢Nagle的算法),然后通过一次系统调用回读。

与在处理空间内部移动内存相比,执行系统调用并将数据从内核空间移动到用户空间是一项非常昂贵的操作。这就是为什么执行尽可能少的系统调用很重要(但不能少于)。

当Japronto接收数据并成功解析出几个请求时,它会尽可能快地执行所有请求,并以正确的顺序将响应粘合回来,然后在一次系统调用中写回。事实上,内核可以帮助胶合部分,这要归功于Japronto尚未使用的分散聚集IO系统调用。

请注意,这并非总是可行,因为有些请求可能需要很长时间,等待它们会不必要地增加延迟。

调整启发式时要小心,并考虑系统调用的成本和预期的请求完成时间。

Japronto使用内插法给出了分组连续数据的1,214,440 RPS中位数,计算结果为第50百分位数

除了延迟写入流水线客户端外,还有其他一些代码使用的技术。

Japronto几乎完全由C 语言编写。解析器,协议,连接收割者,路由器,请求和响应对象被写为C扩展。

在明确询问之前,Japronto努力推迟创建其内部结构的Python对象。例如,只有在视图中请求时才会创建标题字典。所有的标记边界都已经标记过,但是标准键的标准化,以及第一次访问时创建了几个str对象。

Japronto依靠优秀的picohttpparser C库来解析状态行,头文件和分块的HTTP消息主体。Picohttpparser直接采用现代CPU中具有SSE4.2扩展(几乎所有10年前的x86_64 CPU都有)的文本处理指令来快速匹配HTTP令牌的边界。I O由super awesome uvloop处理,它本身就是libuv的一个包装。在最低级别,这是epoll系统调用的桥梁,提供读写准备就绪的异步通知。

Picohttpparser依赖SSE4.2和CMPESTRI x86_64进行解析

Python是一种垃圾收集语言,因此在设计高性能系统时需要注意,以免不必要地增加垃圾收集器的压力。Japronto的内部设计试图避免参考周期,并根据需要尽可能少地分配解除分配。它通过将一些对象预先分配到所谓的舞台上来实现这一点。它还会尝试重用Python对象,以便将来的请求不再引用而不是抛弃它们。

所有的分配都是以4KB的倍数完成的。内部结构是精心布局的,这样经常使用的数据在内存中足够接近,从而最大限度地减少了缓存未命中的可能性。

Japronto试图不必在缓冲区之间进行复制,并且在现场进行了许多操作。例如,它在路由器进程匹配之前对路径进行百分比解码。

目前Japronto一个非常坚实的功能集:

我将本篇博文的代码都已经打包放在我的群里啦。
如果需要代码或者需要有关python的资料都可以加。四九一,三零八,六五九,备注跨界,我就明白是你了

上一篇下一篇

猜你喜欢

热点阅读