什么控制 Celery 工作线程?
What controls Celery worker threads?
我有一个使用此命令启动的 Celery 工作进程:
celery multi start worker --app=xyz.celery --queue="xyz"
--pidfile="/var/run/xyz/%n.pid"
--pool=gevent --concurrency=500 --time-limit=1800
我的任务对 gevent 并发是安全的,但对 OS 线程不安全,我看到一个间歇性错误,表明它们被多个 OS 运行 ] 线程。
查看工作进程,似乎总共有7个线程:
$ ps -ef | grep "celery worker"
nobody 26577 1 0 Mar06 ? 00:46:43 /usr/bin/python -m celery worker
--time-limit=1800 --concurrency=500 --pool=gevent --app=xyz.celery
--queue=xyz --pidfile=/var/run/xyz/xyz-worker.service.pid --hostname=worker@xyz
$ cat /proc/26577/status
Name: python
...
...
Threads: 7
...
(我也可以通过 ps -T 或通过 htop 看到 worker 有这 7 个线程)
在我有类似设置的其他服务器上,我有 4 个线程而不是 7 个。我不知道是什么控制了它。我在 Celery 文档中没有看到任何解释它的内容。
我所有的服务器都有 4 个 CPU,所以显然不是这样。从我读过的所有内容来看,它应该只是一个线程,因为我已经告诉它使用 gevent 进行并发。
为什么要用1个以上,是什么决定了个数,如何控制?
原来这些线程是由gevent维护的但是they're not used to run user code:
By default, gevent will create threads to handle DNS resolution in a
cooperative fashion (invisibly to the caller). gevent will never run
user code in a separate thread implicitly without being explicitly
instructed to do so by direct usage of a thread pool
我有一个使用此命令启动的 Celery 工作进程:
celery multi start worker --app=xyz.celery --queue="xyz"
--pidfile="/var/run/xyz/%n.pid"
--pool=gevent --concurrency=500 --time-limit=1800
我的任务对 gevent 并发是安全的,但对 OS 线程不安全,我看到一个间歇性错误,表明它们被多个 OS 运行 ] 线程。
查看工作进程,似乎总共有7个线程:
$ ps -ef | grep "celery worker"
nobody 26577 1 0 Mar06 ? 00:46:43 /usr/bin/python -m celery worker
--time-limit=1800 --concurrency=500 --pool=gevent --app=xyz.celery
--queue=xyz --pidfile=/var/run/xyz/xyz-worker.service.pid --hostname=worker@xyz
$ cat /proc/26577/status
Name: python
...
...
Threads: 7
...
(我也可以通过 ps -T 或通过 htop 看到 worker 有这 7 个线程)
在我有类似设置的其他服务器上,我有 4 个线程而不是 7 个。我不知道是什么控制了它。我在 Celery 文档中没有看到任何解释它的内容。
我所有的服务器都有 4 个 CPU,所以显然不是这样。从我读过的所有内容来看,它应该只是一个线程,因为我已经告诉它使用 gevent 进行并发。
为什么要用1个以上,是什么决定了个数,如何控制?
原来这些线程是由gevent维护的但是they're not used to run user code:
By default, gevent will create threads to handle DNS resolution in a cooperative fashion (invisibly to the caller). gevent will never run user code in a separate thread implicitly without being explicitly instructed to do so by direct usage of a thread pool