为什么多进程无法通过eventlet加速发送HTTP请求

时间:2015-02-06 03:26:55

标签: python python-multiprocessing eventlet

我有一个应用程序来发送一堆HTTP请求。首先,我使用 eventlet 请求来实现它。但是性能太低了。因此,我希望使用多进程加快速度。需要知道的是,服务器将需要 200ms 来处理单个请求(不包括网络传输)。

但是,多进程比原始版本慢。我对这个结果感到非常惊讶!为什么呢?

如下所示的代码,我使用 timeit 来衡量时间。

import eventlet
eventlet.monkey_patch(all=False, socket=True)

import requests

URL = 'http://....'

def send():
    pile = eventlet.GreenPile(20)
    for x in xrange(100):
        pile.spawn(requests.get, URL)
    for x in pile:
        pass

import multiprocessing

def main():
    procs = [multiprocessing.Process(target=send) for _ in range(3)]
    for p in procs:
        p.start()
    for p in procs:
        p.join()

import timeit

if __name__ == '__main__':
    print timeit.timeit(main, number=1)

1 个答案:

答案 0 :(得分:0)

TL; DR:信息不足。 通过纯粹推测,服务器是限制因素(可能是由故意的人为限制或资源匮乏引起的),因此通过添加更多并发请求,您平均每个请求都会变慢。

以下是解释此问题的一种方法:客户端和服务器上的资源数量有限:每次CPU周期,每次内存访问,内存大小,网络带宽。 OS和eventlet合理使用这些资源。这样您就可以估算出单个请求需要多少资源,软件会以合理的模式(接近线性)进行扩展。要从多处理中受益,需要您的客户端进程使单个CPU单元100%忙碌。特别是requests库已经擅长浪费硬件资源,它会导致我尝试过的所有CPU开销最多(httplib,httplib2,urllib)。但是你必须做出很多(数千个)并发请求,或者有非常糟糕/繁忙的CPU才能使其成为瓶颈。

确切的答案需要信息:

  • HTTP客户端和服务器是否同意任何资源?即他们在相同的物理硬件上运行吗?
  • 您在单一进程模式下可以生成的最大请求频率(每秒计数)是多少?调整GreenPile大小以改变并发请求的数量。
  • 您使用多个流程生成的请求的最大频率是多少?调整GreenPile大小和进程数。尝试运行多个独立的Python解释器而无需多处理。
  • 服务器是瓶颈吗?通过在单独的硬件上添加另一个客户端进如果请求频率较高,则服务器不是瓶颈。如果请求频率随着客户端的增加而下降,那么服务器已经在极限运行,多处理只会让事情变得更糟。
  • 请求时间分布是多少?在220/300/400/500/1000 /更多ms中完成了多少百分比的请求?
  • 什么是网络延迟/带宽?什么是请求/响应大小?那你的网络是否饱和?

回答这些问题将为您提供关于内部和客户/服务器之间正在发生的事情的出色直觉。

相关的Github问题:https://github.com/eventlet/eventlet/issues/195