解决SageMaker auto-stop-idle无法检测Papermill致实例提前关停问题
问题根因
AWS官方提供的auto-stop-idle生命周期脚本默认仅检测两类活动判定实例是否空闲:
- Jupyter服务侧的API请求、内核代码执行记录
- 实例上绑定到Jupyter会话的活跃内核进程CPU占用情况
Papermill执行Notebook时是独立于Jupyter Web会话的Python进程,不管是手动在终端启动、还是通过定时/调度任务触发,都不会被默认的内核活动逻辑捕获,因此会被脚本误判为空闲,达到阈值后自动关停实例。
可行调整方案
按侵入性从低到高排序,可按需选择:
方案1:调度逻辑中临时启停自动停服规则
如果你的Papermill任务有明确的启动、结束触发点,不需要修改auto-stop脚本核心逻辑,直接在任务前后加控制命令即可:
- Papermill任务启动前执行命令,暂停自动关停定时任务:
sed -i 's/^/#/' /etc/cron.d/auto-stop-idle
- 所有Papermill任务执行完成后执行命令,恢复自动关停规则并重置空闲计时器:
sed -i 's/^#//' /etc/cron.d/auto-stop-idle echo $(date +%s) > /home/ec2-user/SageMaker/auto-stop-idle/.idle_time
注意:如果任务执行中出现异常中断,会导致自动关停规则一直处于关闭状态,需要额外加异常捕获逻辑兜底。
方案2:修改auto-stop脚本,新增Papermill进程检测
这个方案最通用,不需要调整Papermill侧的执行逻辑,只需要补一段进程检测规则:
- 找到auto-stop脚本的核心执行文件,默认路径为
/home/ec2-user/SageMaker/auto-stop-idle/autostop.py(生命周期配置中会把该脚本写到这个路径,由cron定时触发) - 在脚本的空闲判定逻辑最前面,加入Papermill进程检测代码,检测到运行中任务时直接重置空闲计时器,跳过关停判断:
import psutil import time # 检测运行中/非僵尸状态的papermill进程 papermill_active = False for proc in psutil.process_iter(attrs=['name', 'cmdline', 'status']): try: proc_name = proc.info['name'] or '' proc_cmd = proc.info['cmdline'] or [] if 'papermill' in proc_name or any('papermill' in seg for seg in proc_cmd): if proc.info['status'] not in (psutil.STATUS_ZOMBIE, psutil.STATUS_DEAD): papermill_active = True break except (psutil.NoSuchProcess, psutil.AccessDenied): continue # 存在活跃Papermill任务时,重置空闲时间后直接退出 if papermill_active: with open(IDLE_TIME_FILE, 'w') as f: f.write(str(time.time())) sys.exit(0)
- 保存修改后,不需要重启实例,下一次cron触发检测时就会自动加载新逻辑。
该逻辑可以覆盖所有环境下启动的Papermill进程,包括conda虚拟环境、后台nohup启动的任务。
方案3:加心跳保活文件适配现有检测逻辑
如果不想改动进程检测相关逻辑,可以通过心跳文件的方式让现有脚本识别到活动:
- 在所有需要通过Papermill执行的Notebook最开头加入心跳线程,每隔1分钟更新一次保活文件的修改时间:
import os import time import threading def papermill_keepalive(): keepalive_path = "/home/ec2-user/SageMaker/.papermill_keepalive" # 先创建空文件 open(keepalive_path, 'a').close() while True: # 更新文件最后修改时间为当前时间 os.utime(keepalive_path, None) time.sleep(60) # 启动后台保活线程,随任务退出自动终止 threading.Thread(target=papermill_keepalive, daemon=True).start()
- 修改auto-stop脚本的空闲判定逻辑,把保活文件的最后修改时间纳入判断维度:只要文件最后修改时间距当前时间小于设定的空闲阈值,就判定为非空闲,不执行关停。
验证步骤
修改完成后可以做简单校验避免误关停:
- 手动启动一个耗时超过空闲阈值的Papermill测试任务
- 等待时长超过设定的空闲阈值后,查看
/var/log/auto-stop-idle.log日志,确认逻辑识别到Papermill活动、跳过了关停操作 - 测试任务结束后,等待达到空闲阈值,确认实例可以正常自动关停
内容的提问来源于stack exchange,提问作者Led
相关产品推荐
相关产品推荐

