Использование памяти не уменьшается даже после успешного завершения задания
У меня добавлено задание в 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 в качестве оболочки и все еще может видеть проблемы с памятью.