Использование памяти не уменьшается даже после успешного завершения задания

У меня добавлено задание в apscheduler, который загружает некоторые данные в память, и я удаляю все объекты после завершения задания. Теперь, если я запускаю эту работу с python, она работает успешно, и падение памяти после успешного завершения процесса. Но в случае apscheduler использование памяти не снижается. Я использую BackgroundScheduler. Заранее спасибо.

2 ответа

Я выполнял довольно много задач через apscheduler. Я подозревал, что эта настройка привела к ошибкам R14 на Heroku, с ежедневной перегрузкой памяти дино, сбоями и перезагрузками. Поэтому я запустил еще один динамометрический стенд и запланировал очень частое выполнение нескольких заданий.

Посмотрев вкладку метрик в Heroku, сразу стало ясно, что виноват apscheduler.

Мне было рекомендовано удалять задания после их запуска. Но это, конечно, плохая идея при запуске заданий cron и interval, поскольку они больше не запускаются.

Что в конечном итоге решило это, так это настройка threadpoolexecutioner (снижение максимального количества рабочих), см. Этот ответ в Stackru, а также этот и этот пост на Github. Я определенно предлагаю вам прочитать документацию по этому поводу.

Другие ресурсы диагностики: 1, 2.

Пример кода:

import logging
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.schedulers.blocking import BlockingScheduler
from tests import overloadcheck

logging.basicConfig()
logging.getLogger('apscheduler').setLevel(logging.DEBUG)

sched = BlockingScheduler(
    executors={
        'threadpool': ThreadPoolExecutor(max_workers=9),
        'processpool': ProcessPoolExecutor(max_workers=3)
        }
)

@sched.scheduled_job('interval', minutes=10, executor='threadpool')
def message_overloadcheck():
    overloadcheck()

sched.start()

Или, если вам нравится, что я люблю выполнять тяжелые задачи - попробуйте ProcessPoolExecutor в качестве альтернативы или дополнения к ThreadPool, но обязательно вызывайте его из определенных заданий в таком случае.

Обновление: вам также необходимо импортировать ProcessPoolExecutor, если вы хотите его использовать, добавив это в код.

На всякий случай, если кто-то использует Flask-APScheduler и имеет проблемы с утечкой памяти, мне потребовалось время, чтобы понять, что он ожидает, что любые параметры конфигурации будут в вашем Flask Config, а не при создании экземпляра планировщика.

Итак, если вы (как и я) сделали что-то вроде этого:

      from flask_apscheduler import APScheduler
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.executors.pool import ThreadPoolExecutor

bg_scheduler = BackgroundScheduler(executors={'threadpool': ThreadPoolExecutor(max_workers=1)})
scheduler = APScheduler(scheduler=bg_scheduler)

scheduler.init_app(app)
scheduler.start()

тогда по какой-либо причине, когда задания выполняются в контексте запроса Flask, он не распознает исполнителя, «пул потоков» или любые другие параметры конфигурации, которые вы могли установить.

Однако, если вы установите эти же параметры в классе Flask Config как:

      class Config(object):
    #: Enable build completion checks?
    SCHEDULER_API_ENABLED = True
    #: Sets max workers to 1 which reduces memory footprint
    SCHEDULER_EXECUTORS = {"default": {"type": "threadpool", "max_workers": 1}

    # ... other Flask configuration options

а затем сделайте (обратно в основной скрипт)

      scheduler = APScheduler()
scheduler.init_app(app)
scheduler.start()

то параметры конфигурации на самом деле сделать набор ГЭТ. Я предполагаю когда я звонил в исходном скрипте Flask-APScheduler увидел, что я не установил ни одного из этих параметров в своей конфигурации Flask, и поэтому перезаписал их значениями по умолчанию, но не уверен на 100%.

Тем не менее, надеюсь, это поможет любому, кто пробовал лучший ответ, но также использует Flask-APScheduler в качестве оболочки и все еще может видеть проблемы с памятью.

Другие вопросы по тегам