天天看點

celery占用大記憶體-記憶體洩漏

問題發現

本來top指令檢視伺服器實時記憶體情況,  突然發現32G記憶體 celery 占用到12%,  記憶體占用都快4G了.

  1. ​top​

    ​​指令下,​

    ​M​

    ​​鍵開啟按​

    ​MEM​

    ​​列排序的程序清單,按​

    ​H​

    ​​則檢視線程清單,由于​

    ​worker​

    ​沒有子線程,是以隻顯示一條記錄;
  2. 按​

    ​c​

    ​​指令,開始​

    ​COMMAND​

    ​列詳細情況,可以找到對應的程序啟動者;
  3. 按​

    ​o​

    ​​鍵,開啟篩選功能,輸入​

    ​COMMAND=celery​

    ​​隻顯示​

    ​celery​

    ​名的程序清單;

原因

預設情況下,celery的worker是工作程序可以被新任務替換之前執行的最大任務數, 預設值是沒有限制。

見​​官網說明​​

"""
celery配置
"""

from celery.schedules import crontab

# 中間人
BROKER_URL = 'redis://:[email protected]/x'

worker_prefetch_multiplier = 4  # celery worker并發數
worker_max_tasks_per_child = 2  # 每個worker最大執行任務數


# 指定時區,不指定預設為 'UTC'
CELERY_TIMEZONE = 'Asia/Shanghai'

# 指定導入的任務子產品
CELERY_IMPORTS = (
    'celery_app.tasks',
)      

需要配置celery設定 但是官網寫的參數在執行執行過程中發生錯誤 "無法将新設定名稱與舊設定名稱混合使用"

Cannot mix new setting names with old setting names, please

rename the following settings to use the old format:

worker_max_tasks_per_child           -> CELERYD_MAX_TASKS_PER_CHILD

worker_prefetch_multiplier           -> CELERYD_PREFETCH_MULTIPLIER

需要修改配置名稱:

"""
celery配置
"""

from celery.schedules import crontab

# 中間人
BROKER_URL = 'redis://:[email protected]/x'

CELERYD_PREFETCH_MULTIPLIER = 4  # celery worker并發數
CELERYD_MAX_TASKS_PER_CHILD = 2  # 每個worker最大執行任務數

# 指定時區,不指定預設為 'UTC'
CELERY_TIMEZONE = 'Asia/Shanghai'

# 指定導入的任務子產品
CELERY_IMPORTS = (
    'celery_app.tasks',
)      

重新啟動

執行

celery beat -A celery_app -l info --detach      

啟動celery,通過ps -ef | grep celery可以看到兩個celery worker程序(8226,8228)

利用celery worker進行某個任務,當worker沒有執行到最大任務時(即銷毀重建),每執行一次任務占用記憶體必然有所增加,任務數為9,10時(celery均勻排程,并發數*最大任務數),分别有原8228 worker被銷毀,重新建立9386 worker及原8226 worker被銷毀,重新建立9564 worker,此時,運作第9次時,占用總記憶體有所下降,運作第10次時,總記憶體回到初如值,同樣任務執行第19、20次情況類似。

celery并發計算規則

celery任務并發隻與celery配置項CELERYD_CONCURRENCY 有關,與CELERYD_MAX_TASKS_PER_CHILD沒有關系,即CELERYD_CONCURRENCY=2,隻能并發2個worker,此時任務處理較大的檔案時,執行兩次可以看到兩個task任務并行執行,而執行第三個任務時,開始排隊,直到兩個worker執行完畢。