celery worker 并发和多 worker 怎么理解?

2019-08-21 10:42:09 +08:00
 dwadewyp

celery 的单个 worker 的 concurrency 和多个 workers 怎么理解?

5809 次点击
所在节点    Python
12 条回复
letking
2019-08-21 10:46:02 +08:00
celery 没有单 worker 的并发吧,它的并发就是靠多 worker 实现的。
gunicorn 是多 worker,且单 worker 可以并发的。
BigBrother1024
2019-08-21 10:58:26 +08:00
gevent
dwadewyp
2019-08-21 11:17:43 +08:00
@letking 我的理解是 一个 worker 进程会通过 python 的 mutliprocessing 实现多线程达到并发处理多任务,所以不会占用多余的内存,多 worker 可以理解为是多进程, 不知道这样的理解对不对
vipppppp
2019-08-21 11:38:35 +08:00
一个工厂(worker)有一个员工(单进(线)程),为了提高效率,请多了几个员工一起工作(单 worker 多进程)
为了防止这个工厂断电无法工作,那么多建了几个工厂,每个工厂有多个员工(多 worker 多进程)
---------------------
实际上都是在实现并发

单 worker 可以开 n 个进程进行工作,一个 worker 挂了往往所有进程都会挂掉
多 worker 假设为 m 个,可以理解为分布式,为了防止一个 worker 挂了(或者性能不足等原因),导致无法工作
那么能够并发处理的任务数量理论上为 m * n
IMRES
2019-08-21 11:45:19 +08:00
一个 worker 就是一个消费者,它可以并发地消费任务,并发的模式取决于你的配置,可以使用的有 threading, eventlet 等等。
例如这条命令 ` celery -A proj worker -P eventlet -c 1000` 会启动一个 worker, 这个 worker 的并发数为 1000。


多个 worker 就是指有不同的 worker id 的消费者。
dwadewyp
2019-08-21 14:02:15 +08:00
@vipppppp 具体这两种的使用场景 如何区分?
Ehco1996
2019-08-21 14:15:39 +08:00
你可以简单的把一个 worker 理解为一个单独的进程
而这个单独的进程又可以通过不同的并发模型来达到并发的效果

使用场景的话对 worker 的数量没有特殊要求
但不同的使用场景应该用不同并发模型
比如高 io 的情况下(举个例子 批量推送微信提醒)可以考虑用异步 io 的并发模型,在 celery 里的配置可以考虑用 gevent 这种
vipppppp
2019-08-21 14:35:15 +08:00
@dwadewyp
我还以为我描述的很清楚了...

一般 worker(不仅 celery,很多设计都是这样)指一个调度主进程 + 多个子工作进程

一个 worker 有什么缺点:
1. 如果这个 worker 的主进程挂了,那么整个任务系统都崩了。
2. 再往深点,如果你服务端 master 发送的任务速度很快,远大于 worker 主进程去分发任务的速度,可能会影响效率(但这种情况很少,而且这种框架一般都是容忍延迟的)
3. 部署 worker 这台机器挂了,那么你的任务系统都崩了
4. 这台机器的资源(cpu,内存,IO 等)无法满足你的需求

--------------------------
比较常见的是在不同机器部署多个 worker
在不考虑机器和进程挂掉但情况,其实一个 worker 开 8 个进程和 2 个 worker 每个开 4 个进程的效率是接近的。

-------------------------
感觉 lz 没有什么分布式的概念,可以多了解一些
dwadewyp
2019-08-21 14:51:04 +08:00
@vipppppp 所以你看我的理解对么? 比较常见的部署多 worker 情况 是为了保证任务系统不会因为主进程挂掉 而致使崩掉, 而保证任务的并发是通过配置 celery 并发模式来定的.
letking
2019-08-21 22:11:57 +08:00
@dwadewyp
celery 里面的-c 参数指定的是并发度,而-P 参数指定并发的实现方式,有 prefork (default)、eventlet、gevent 等,prefork 就是多进程的方式去实现并发。
你理解的多 worker 对应到多个进程,每个 worker (进程)自己内部还能并发是 gunicorn 的方式。gunicorn 的-w 参数指定有几个 worker (即几个进程),-k 参数指定每个 worker 的并发方式,可以是多线程或者多协程,也可以指定为 sync,表示 worker 是同步的,即不能并发。
letking
2019-08-21 22:23:17 +08:00
比如 gunicorn 的-w 10 -k sync 和 celery 的-c 10 -P prefork 是等价的,都是创建 10 个进程去做并发,并发度最高就是 10。

再例如 celery 的-c 10 -P gevent 表示创建 10 个 gevent 协程去做并发,最高并发度也是 10。而 gunicorn 的-w 10 -k gevent,表示的是创建 10 个进程,且每个进程都是 gevent 异步的,这个并发度就很高了。
lenqu
2019-12-28 17:26:06 +08:00
1. 一个 worker 是一个进程
2. prefork (default) 并发方式是多进程,启动多个 worker
3. gevent 并发方式是多协程,在一个 worker 下启动多个协程

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/593748

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX