Tri*_*tan 4 python concurrency celery eventlet
正如celery 文档 中提到的,对于事件 I/O(例如异步 HTTP 请求),eventlet 池应该比 prefork 池更快。
他们甚至提到
“在使用 feed hub 系统进行的非正式测试中,Eventlet 池每秒可以获取并处理数百个 feed,而 prefork 池则花费 14 秒处理 100 个 feed。”
然而,我们无法产生任何与此类似的结果。完全按照描述运行示例任务、urlopen和crawl并打开数千个url,看来 prefork 池几乎总是表现得更好。
我们测试了各种并发性(并发性为 200 的 prefork,并发性为 200、2000、5000 的 eventlet)。在所有这些情况下,使用 prefork 池,任务都可以在更少的秒内完成。运行的计算机是 2014 年 Macbook Pro,运行 RabbitMQ 服务器。
我们希望同时发出数千个异步 HTTP 请求,并且想知道 eventlet 池是否值得实现?如果是的话,我们还缺少什么?
python -V && pip freeze 的结果是:
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
Run Code Online (Sandbox Code Playgroud)
使用的测试代码(几乎完全来自文档):
>>> 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()
Run Code Online (Sandbox Code Playgroud)
小智 8
即使无需编写非阻塞风格的代码,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)
Run Code Online (Sandbox Code Playgroud)
同样的方式运行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()
Run Code Online (Sandbox Code Playgroud)
假设您有一个具有 100 个子进程的预派生工作线程和另一个具有 1000 个绿色线程的工作线程,您将能够看到显着的差异。
| 归档时间: |
|
| 查看次数: |
4002 次 |
| 最近记录: |