V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
akmonde
V2EX  ›  Python

V 币急等感谢---关于 djcelery 配置 queue 不生效 [也谈 workflow 子任务锁死问题]

  •  
  •   akmonde · 2018-09-27 20:49:11 +08:00 · 1782 次点击
    这是一个创建于 2249 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我 celery 版本为 v3.1.25 ,django 和 celery 的启动项如下:

    celery -A proj-test worker -n workerA.%h --concurrency=2
    celery -A proj-test worker -n workerB.%h --concurrency=2
    python manage.py celeryd -B
    python manage.py celery beat
    python manage.py runserver 0.0.0.0:8000
    
    

    这样是可以运行的,不过好像由于我在 celery 的 task 里面,使用了 workflow 的 chord/group 进行 subtask 分发,导致 subtask 过多时,因为 concurrency 有限,beat 任务( beat_function )会因此堵塞结束不掉。

    大概代码如下,下面至少有两个 chord:

    @task
    def beat_function():
    	xxfunc1.delay()
        xxfunc2.delay()
    	time.sleep(5)
        chord((test1.s(x) for x in xs) , test2.s())
        chord((test3.s(y) for y in ys) , test4.s())
        
    

    所以我有个问题,想问问大家能否指定 beat 的 queue。

    让它不会占用其他 subtask 运行的 worker 容量,这样就算 beat 所在的 queue 在阻塞,等到 subtask 运行完毕,这边 queue 也会结束相应的 beat 任务。

    我是这样弄得,queue 配置如下:

    CELERY_QUEUES = {
        "celery_beat": { 
            "exchange": "celery_beat",
            "exchange_type": "direct",
            "routing_key": "celery_beat"
        },
    }
    
    

    尝试过的 beat 运行方式如下两种

    python manage.py celeryd -B -Q celery_beat
    

    也尝试了下面的运行法子:

    python manage.py celery worker  -B -Q celery_beat
    

    不过始终不能把 beat 任务运行起来,每次一加 queue 似乎 beat 就失效了。

    尝试过同时单独运行,也失败:

    python manage.py celery worker --beat
    python manage.py celery worker -Q celery_beat
    
    

    希望大佬们,帮忙解答下面两个问题:

    • 单独 queue 运行 beat 任务能否解决我那个死锁问题?

    我不能每次手动结束 beat 任务,确实结束了能解决某一次死锁,那些 subtask 能运行完。我曾尝试设置任务超时,单个 chord 的时可用,该 chord 可以运行完结,不过后面还有 chord 分发其他子任务就 gg 了,也就是说只能运行完第一个 chord,比如我上面举的例子。

    • 我的上面的运行 beat 的方法是否有误,加了 queue 配置是否有误或者不完整,导致我 beat 任务运行不起来?

    我想要实现的是,单个 queue 指定的那些 worker,运行所有的 beat 任务,现在的情况是所有的 worker 都会去抢 beat 任务,结果可能导致了部分 beat 任务阻塞。

    8 条回复    2018-10-09 13:57:33 +08:00
    akmonde
        1
    akmonde  
    OP
       2018-09-28 12:02:32 +08:00
    Woc,没人给点建议么,屌大的大佬们呢,都换上女装去泡吧了么?!
    YaphetYin
        2
    YaphetYin  
       2018-09-29 22:23:22 +08:00
    beat 单独起啊,celery -A xxx beat
    akmonde
        3
    akmonde  
    OP
       2018-09-30 13:00:29 +08:00
    @YaphetYin 单独起了,会出现我上述的死锁问题,所以才想把 beat 任务单独给一个 queue。
    但是结果好像不尽如人意,不知道我 router 和 queue 是否配置有问,还是压根不能这样做。
    YaphetYin
        4
    YaphetYin  
       2018-10-01 04:47:06 +08:00 via iPhone
    @akmonde
    call subtask 的时候不要同步 call,官方有针对死锁的说明
    akmonde
        5
    akmonde  
    OP
       2018-10-01 11:33:56 +08:00
    @YaphetYin 有看过,3.2 以后好像还针对这种情况抛出错误,只是实在没想到更优的解法,来解决一堆 subtask 的问题。
    YaphetYin
        6
    YaphetYin  
       2018-10-01 12:20:44 +08:00   ❤️ 1
    @akmonde 可以把你的任务结构贴一下看看?
    akmonde
        7
    akmonde  
    OP
       2018-10-01 17:53:31 +08:00
    @YaphetYin 嗯,回头我整理下贴出来,代码在公司,兄 dei 长假快乐~
    akmonde
        8
    akmonde  
    OP
       2018-10-09 13:57:33 +08:00
    @YaphetYin 后来用单个 chord 串联了执行了一堆任务,暂时解决了,虽然法子有点笨,老兄回头有空看看我最新的提问...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2871 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:06 · PVG 17:06 · LAX 01:06 · JFK 04:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.