Celery与Redis后端的问题

2 投票
2 回答
7091 浏览
提问于 2025-04-17 12:36

我现在有一个系统,使用了celery和redis来处理一些异步任务,比如发送邮件、获取社交数据、爬虫等等。一切运行得很好,但我在想怎么监控这个系统(也就是查看排队的消息数量)。我开始查看celery的源代码,但决定在这里发问。首先,这是我的配置:

BROKER_BACKEND                  = "redis" 
BROKER_HOST                     = "localhost" 
BROKER_PORT                     = 6379 
BROKER_VHOST                    = "1" 
REDIS_CONNECT_RETRY     = True 
REDIS_HOST                              = "localhost" 
REDIS_PORT                              = 6379 
REDIS_DB                                = "0" 
CELERY_SEND_EVENTS                      = True 
CELERYD_LOG_LEVEL               = 'INFO' 
CELERY_RESULT_BACKEND           = "redis" 
CELERY_TASK_RESULT_EXPIRES      = 25 
CELERYD_CONCURRENCY             = 8 
CELERYD_MAX_TASKS_PER_CHILD = 10 
CELERY_ALWAYS_EAGER                     =True

我现在想做的第一件事是监控我的队列中有多少消息。我猜在后台,redis其实就是在一个列表中添加和删除任务,虽然我在代码中找不到相关的内容。所以我模拟了一下,启动了大约100个任务,想在redis中找到它们:

我的celeryd是这样运行的:

python manage.py celeryd -c 4 --loglevel=DEBUG -n XXXXX --logfile=logs/celery.log

所以我应该一次只有4个并发的工作者在运行……

我有两个不明白的地方:

问题1:

在我排队了100个任务后,去redis中查看时,只看到了以下内容:

$ redis-cli 
redis 127.0.0.1:6379> keys * 
1) "_kombu.binding.celery" 
redis 127.0.0.1:6379> select 1 
OK 
redis 127.0.0.1:6379[1]> keys * 
1) "_kombu.binding.celery" 
2) "_kombu.binding.celeryd.pidbox" 
redis 127.0.0.1:6379[1]>

我似乎找不到这些任务,无法知道有多少个在排队(技术上来说,应该是96个,因为我只支持4个并发任务)。

问题2:

$ ps aux | grep celeryd | cut -c 13-120 
 41258   0.2  0.2  2526232   9440 s004  S+    2:27PM   0:07.35 python 
manage.py celeryd -c 4 --loglevel=DEBU 
 41261   0.0  0.1  2458320   2468 s004  S+    2:27PM   0:00.09 python 
manage.py celeryd -c 4 --loglevel=DEBU 
 38457   0.0  0.8  2559848  34672 s004  T    12:34PM   0:18.59 python 
manage.py celeryd -c 4 --loglevel=INFO 
 38449   0.0  0.9  2517244  36752 s004  T    12:34PM   0:35.72 python 
manage.py celeryd -c 4 --loglevel=INFO 
 38443   0.0  0.2  2524136   6456 s004  T    12:34PM   0:10.15 python 
manage.py celeryd -c 4 --loglevel=INFO 
 84542   0.0  0.0  2460112      4 s000  T    27Jan12   0:00.74 python 
manage.py celeryd -c 4 --loglevel=INFO 
 84536   0.0  0.0  2506728      4 s000  T    27Jan12   0:00.51 python 
manage.py celeryd -c 4 --loglevel=INFO 
 41485   0.0  0.0  2435120    564 s000  S+    2:54PM   0:00.00 grep 
celeryd 
 41264   0.0  0.1  2458320   2480 s004  S+    2:27PM   0:00.09 python 
manage.py celeryd -c 4 --loglevel=DEBU 
 41263   0.0  0.1  2458320   2480 s004  S+    2:27PM   0:00.09 python 
manage.py celeryd -c 4 --loglevel=DEBU 
 41262   0.0  0.1  2458320   2480 s004  S+    2:27PM   0:00.09 python 
manage.py celeryd -c 4 --loglevel=DEBU 

如果有人能为我解释一下这个情况,那就太好了。

2 个回答

1

我从来没用过Celery,但如果你想了解它在做什么,可以试试这个方法:用redis-cli连接到Redis实例,然后运行monitor命令。这个命令会显示所有正在对Redis数据库执行的命令。这样你就能清楚地看到发生了什么。

9

你的配置里有 CELERY_ALWAYS_EAGER = True。这意味着任务会在本地运行,所以你在Redis里看不到这些任务。根据文档的说明:http://celery.readthedocs.org/en/latest/configuration.html#celery-always-eager

CELERY_ALWAYS_EAGER

如果这个设置为True,所有的任务都会在本地执行,直到任务完成才会继续。使用apply_async()和Task.delay()时,会返回一个EagerResult实例,这个实例模拟了AsyncResult的API和行为,只不过结果已经被计算出来了。

也就是说,任务会在本地执行,而不是发送到队列里去。

撰写回答