Celery + Eventlet池不会提高异步Web请求的执行速度

时间:2015-04-29 19:32:31

标签: python concurrency celery eventlet

作为mentioned in the celery docs,eventlet池应该比用于事件I / O的prefork池更快,例如异步HTTP请求。

他们甚至提到了

  

“在使用Feed中心系统的非正式测试中,Eventlet池可以   在prefork中,每秒获取并处理数百个feed   池花了14秒处理100个饲料。“

但是,我们无法产生任何类似的结果。完全按照描述运行example tasks urlopen 抓取并打开数千个网址,看起来prefork池几乎总是表现得更好。

我们测试了各种各样的并发(prefork with concurrency 200,eventlet with concurrencies 200,2000,5000)。在所有这些情况下,使用prefork池可以在更短的时间内完成任务。正在运行的计算机是运行RabbitMQ服务器的2014 Macbook Pro。

我们希望一次发出数千个异步HTTP请求,并且想知道eventlet池是否值得实现?如果是,我们缺少什么?

结果      python -V&& pip冻结 是:

Python 2.7.6
amqp==1.4.6
anyjson==0.3.3
billiard==3.3.0.20
bitarray==0.8.1
celery==3.1.18
dnspython==1.12.0
eventlet==0.17.3
greenlet==0.4.5
kombu==3.0.26
pybloom==1.1
pytz==2015.2
requests==2.6.2
wsgiref==0.1.2

使用的测试代码(几乎完全来自文档):

>>> from tasks import urlopen
>>> from celery import group
>>> LIST_OF_URLS = ['http://127.0.0.1'] * 10000 # 127.0.0.1 was just a local web server, also used 'http://google.com' and others
>>> result = group(urlopen.s(url)
...                     for url in LIST_OF_URLS).apply_async()

1 个答案:

答案 0 :(得分:1)

即使不编写非阻塞样式代码,Eventlet也允许您拥有比prefork更大的并发性。 Eventlet优于prefork的典型情况是,您有许多阻塞I / O绑定操作(例如time.sleeprequests.get到高延迟网站)。您对本地主机或“http://google.com”的请求似乎得到的响应太快而不能被视为I / O限制。

您可以尝试这个玩具示例,了解基于Eventlet的池如何在I / O绑定操作中表现更好。

# in tasks.py add this function
import time

# ...

@task()
def simulate_IO_bound():
    print("Do some IO-bound stuff..")
    time.sleep(5)

以相同的方式运行worker,最后生成任务

from tasks import simulate_IO_bound

NUM_REPEAT = 1000

results = [simulate_IO_bound.apply_async(queue='my') for i in range(NUM_REPEAT)]
for result in results:
    result.get()

假设你有一个拥有100个子流程的prefork worker和另一个拥有1000个绿色线程的worker,你将能够看到一个巨大的差异。

相关问题