首页 > 解决方案 > 带有 Redis 和 Django 的 Celery 在长时间运行的任务中给出 WorkerLostError

问题描述

我有一个长期运行的 Celery 任务,它计算一个特性的 PDP。以下是正在运行的共享任务:

@shared_task
def get_pdp_single(bst, train_df, feature, value, f_id=-1):

    x_temp = train_df.copy()
    x_temp.iloc[:, f_id] = value

    data = xgb.DMatrix(x_temp, feature_names=x_temp.columns.tolist())

    predictions = (bst.predict(data))

    avg_predictions = np.mean(predictions)

    result_dict = {
        "feature": feature,
        "avg_predictions": avg_predictions.item()
    }

    return result_dict

我正在计算构建的 XGBoost 模型中采用的所有功能的 Hstatistics。所以,我们有很多这样的任务在 Broker (Redis) 中排队。为此,大约 12k 任务被排队到 Redis 中。

我有一个 8 核 16GB 的 VM,我在其上实例化了一个 Celery 工作人员来执行此任务。每个单独的子任务需要大约 40 秒才能完成,这是因为 XGBoost 预测方法需要时间来完成。

在如此长时间运行的任务中,我总是会收到 WorkerLostErrors 并且这是完全不可预测的,何时以及如何发生。但是,我很确定这是因为在代理上排队的任务数量,因为大约 4-5k 任务在相同的设置上运行良好,没有任何问题。

下面是我在 Celery 上获得的堆栈跟踪。

Restarting celery worker (/~/anaconda3/envs/py35_clone_canary/bin/celery -A ba_tpe_python_service worker -Q staging_celery_queue --loglevel=info)

Traceback (most recent call last):
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/worker/worker.py", line 205, in start
    self.blueprint.start(self)
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/bootsteps.py", line 369, in start
    return self.obj.start()
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/worker/consumer/consumer.py", line 318, in start
    blueprint.start(self)
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/worker/consumer/consumer.py", line 596, in start
    c.loop(*c.loop_args())
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/worker/loops.py", line 74, in asynloop
    state.maybe_shutdown()
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/celery-4.4.0rc3-py3.5.egg/celery/worker/state.py", line 80, in maybe_shutdown
    raise WorkerShutdown(should_stop)
celery.exceptions.WorkerShutdown: 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/~/anaconda3/envs/py35_clone_canary/lib/python3.5/site-packages/billiard-3.6.1.0-py3.5.egg/billiard/pool.py", line 1267, in mark_as_worker_lost
    human_status(exitcode)),
billiard.exceptions.WorkerLostError: Worker exited prematurely: exitcode 70.

我还查看了 Celery 和 Billiard 的 Github 页面上报告的多个问题。该解决方案已被提及为采用最新版本的 Celery 和 Billiard。我从他们各自的 Git 中获取了最新的 master 分支并在我的环境中构建它,但仍然面临同样的问题

使用的 Celery 版本:4.4.0rc3 使用的台球版本:3.6.1.0

请帮助我调试问题。

标签: djangorediscelery

解决方案


推荐阅读