Linux上的Celery不能公平地调度prefork池的任务

时间:2016-06-15 08:10:50

标签: python celery

我在芹菜任务(或理解)中遇到了奇怪的问题。

让我们从cookbook的简单缓存任务开始:

@app.task(name="core.test_dispatching", bind=True)
def test_dispatching(self, *messages):
    import random
    import time

    disk_name_hexdigest = md5(str(hash(messages))).hexdigest()

    lock_id = '{0}-lock-{1}'.format(self.name, disk_name_hexdigest)

    # This snippet from celery cookbook
    acquire_lock = lambda: cache.add(lock_id, 'true', LOCK_EXPIRE)
    release_lock = lambda: cache.delete(lock_id)

    if acquire_lock():
        try:
            time.sleep(random.randint(50, 60))
            logger.info("After sleep got messages: %s", messages)
        finally:
            release_lock()
        return True
    else:
        time.sleep(1)
        logger.info("Someone already processing messages!")
        return False

此代码允许执行许多任务,但只有一个会打印messages(使用相同的参数)。

但是Linux上的默认prefork池(Fedora22 4.0.4-301.fc22.x86_64)调度任务并不是我的预期。

我的芹菜设置:

CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_DEFAULT_RATE_LIMIT = "100/s"
CELERYD_MAX_TASKS_PER_CHILD = 20 
CELERYD_PREFETCH_MULTIPLIER = 2
BROKER_URL = 'redis://localhost:6379/0'

测试代码:

for i in range(30): tasks.test_dispatching.delay("hello", "world!")

预期结果:29个任务在不到30秒内成功完成,一个任务在50-60秒后完成。

实际结果

  1. Fedora22:8个任务在50-60秒内完成,休息时间不到30秒。
  2. Windows10:29个任务在不到30秒内成功完成,一个任务在50-60秒后完成。
  3. 我的设置有问题吗?或者我应该在linux上使用ThreadPool(-p threads)。

0 个答案:

没有答案