作为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()
答案 0 :(得分:1)
即使不编写非阻塞样式代码,Eventlet也允许您拥有比prefork更大的并发性。 Eventlet优于prefork的典型情况是,您有许多阻塞I / O绑定操作(例如time.sleep
或requests.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,你将能够看到一个巨大的差异。