清理数值天气预报业务系统运行目录的几种方法
数值天气预报模式业务系统每天都在固定时间点启动运行,完成从某个时间点开始的预报,称为一个时次。 比如 CMA-GFS 在北京时间 11:40 启动,开始预报从北京时间 8:00 开始的 10 天预报。 一般按照 UTC 时间将北京时间 8 点的预报称为 00 时次。
数值预报模式在运行过程中会生成大量中间数据,比如预处理过的观测资料、模式初始场、侧边界条件、参数文件、模式原始输出等。 如果要保证业务系统每天正常滚动运行,就需要对运行目录中的历史数据进行清理,避免不再使用的历史文件占用宝贵的超算高速存储空间。
目前 CEMC 的数值天气预报业务系统有 3 种组织运行目录的方式:
- 单一目录:所有时次均在同一个目录中运行
- 按时次划分:为了更方便进行查错,模式预报流程一般按照时次(即小时)来安排运行目录。 比如分成 00、06、12、18 等。
- 按起报时间划分:产品制作流程通常只使用当前时次生成的数据,不同时次的产品制作任务能够同时运行,所以可以使用起报时间点来安排运行目录。 比如 2024060512、2024060518、2024060500 等。
清理实时运行目录的复杂性在于不同数据的保留时间不一样。比如模式原始数据文件需要保留几天用于查错,而图片产品则不需要保留太长时间。
本文介绍不同运行目录组织方式下的常用清理方法。
单一目录
因为每个时次都在同一个目录中运行,所以一般在每个时次运行结束前清理中间数据。 有严重的运维隐患,清理中间数据后无法重复运行依赖这些中间数据的任务,不推荐使用。
注:有一种变式是在多个子目录中都保存时次目录,与第二种按时次划分类似
有两种常用的清理方法。
按日期清理
根据过期天数计算得到一个明确的日期,以该日期为关键字查找并删除相关文件。
下面代码来自 CMA-GEPS 的 houskeeping 任务。其中 $YMD
是系统运行的当前日期,例如 20240606。
首先计算得到不同种类数据待删除的日期,与时次字段一起组成起报时间 (DELTIME1
, DELTIME6
):
CLDATE1=$(smsdate -D $YMD -3)
DELTIME1=${CLDATE1}${HH}
CLDATE6=$(smsdate -D $YMD -32)
DELTIME6=${CLDATE6}${HH}
使用起报时间删除相关目录和文件:
cd ${servicesdir}
rm -rf ${DELTIME1}
cd ${rundir}/PRODS/TIGGE
rm -rf *${DELTIME6}*
按过期时间清理
另一种方式利用文件的修改时间进行删除。 业务系统在某个时次运行结束后就不会修改该时次生成的文件,所以文件的修改时间可以作为判断文件是否需要删除的依据。 可以将修改时间超过某个阈值的文件都删掉。
下面代码来自 CMA-TYM 系统的 purge 任务,使用 find 命令查找并删除修改时间超过 1 天的所有以 post 开头的文件,用于清理模式的原始输出数据。
find ${D01DAT} -name "post*" -mtime +1 -print -exec rm -rf {} \;
按时次划分
一般在每天所有时次运行结束后统一清理各个时次目录里的中间数据。
按文件清理
如果时次目录中类似静态资料等数据需要保留,就需要按照文件或者目录来进行筛选,清理时次目录中不需要的中间数据。
下面代码来自 CMA-GFS 系统的 housekeeping 任务,删除了各个时次目录下的和输入数据 (input/…) 和输出文件 (output):
rm -rf ${PF_ANAL}/../00/output/*
rm -rf ${PF_ANAL}/../06/output/*
rm -rf ${PF_ANAL}/../12/output/*
rm -rf ${PF_ANAL}/../18/output/*
rm -rf ${PF_ANAL}/../*/input/atovs/*
rm -rf ${PF_ANAL}/../*/input/gnssro/*
rm -rf ${PF_ANAL}/../*/input/hps/*
rm -rf ${PF_ANAL}/../*/input/gts/*
rm -rf ${PF_ANAL}/../*/input/scatwind/*
rm -rf ${PF_ANAL}/../*/input/background/*
删除整个目录
如果需要保留的数据保存在时次目录之外的独立目录中,就可以将时次目录整体删除。
下面代码来自 CMA-MESO 系统的 copy_dirs 任务,在每个时次启动时运行。 删掉前一轮运行的时次目录,并重新拷贝一份运行基础环境目录作为当前的运行目录。
GRAPESROOT=/g2/op_meso/OPER/WORKDIR/cma_meso_1km/cold/00
if [ -d $GRAPESROOT ];then
rm -fr $GRAPESROOT
fi
cp -r $SYSROOT/bin/GRAPES_MESO6.0_op $GRAPESROOT
按起报时间划分
不同起报时间在不同的目录中,任意两个时次都互不影响,清理空间时只需要删除历史运行目录,无需关心目录中具体都有哪些数据。
删除整个目录
CMA-GFS、CMA-MESO 和 CMA-TYM 的后处理系统中使用正则表达式实现对运行目录的查找和清理。
基本用法
起报时间的格式是年月日时,即 YYYYMMDDHH
,对应正则表达式 [0-9]{10}
。
使用 grep
命令过滤 ls
列出的目录,与待清理时间进行对比,挨个删除符合条件的目录。
下面代码来自 CMA-GFS 后处理流程的 housekeep_final 任务,其中 clear_date
是最近的保留日期,早于该日期的目录均需要删掉。
cycle_run_dir_list=$(ls|grep -E "[0-9]{10}")
for a_cycle_run_dir in ${cycle_run_dir_list}; do
cycle_date=$(echo ${a_cycle_run_dir} | cut -c1-8)
if [[ ${cycle_date} -lt ${clear_date} ]]; then
echo "rm old dir ${a_cycle_run_dir}..."
rm -rf ${a_cycle_run_dir}
echo "rm old dir ${a_cycle_run_dir}...done"
fi
done
进阶用法
CMA-MESO 1KM 系统的后处理流程因为 21 时次和 00 时次运行有重叠,无法正常滚动运行,因此拆成上午和下午两个子流程。 上午流程运行 00/03/06/09 四个时次,下午流程运行 12/15/18/21 四个时次。 除了 ecFlow 流程被拆分成两个外,脚本、运行目录等其余部分均保持一致。
两个流程都有清理运行目录的作业,使用上面一节介绍的脚本可能有发生潜在的冲突。 本节将上述代码修改为支持上午、下午分离的流程,即上午流程仅负责清理上午 4 个时次的目录,下午流程负责另外 4 个时次。
正则表达式如下:
- 上午:
[0-9]{8}(0[0-9]|1[0-1])
- 下午:
[0-9]{8}(1[2-9]|2[0-3])
通过一个 ecFlow 变量判断流程类型,并设置对应的正则表达式。
下面代码来自 CMA-MESO 1KM 系统后处理流程的 housekeep_final 任务。
if [ "w${FLOW_TYPE}" = "wam" ]; then
grep_string="[0-9]{8}(0[0-9]|1[0-1])"
elif [ "w${FLOW_TYPE}" = "wpm" ]; then
grep_string="[0-9]{8}(1[2-9]|2[0-3])"
else
grep_string="[0-9]{10}"
fi
cycle_run_dir_list=$(ls|grep -E "${grep_string}")
for a_cycle_run_dir in ${cycle_run_dir_list}; do
cycle_date=$(echo ${a_cycle_run_dir} | cut -c1-8)
if [[ ${cycle_date} -lt ${clear_date} ]]; then
echo "rm old dir ${a_cycle_run_dir}..."
rm -rf ${a_cycle_run_dir}
echo "rm old dir ${a_cycle_run_dir}...done"
fi
done
存在问题
上述代码在 cycle_run_dir_list
为空时会报错,但一般运行目录中都有以起报时次命名的目录,所以报错概率很小。
总结
下表汇总了以上各种方法,并简要对比了每种方法的优劣势。
运行目录组织方式 | 删除方案 | 优势 | 劣势 |
---|---|---|---|
单一目录 | 按日期清理 | 精确控制不同种类数据的清理时间 | 跳过清理任务会导致漏删 |
按过期时间清理 | 彻底清理过期数据 | 需要仔细调试,避免误删 | |
按时次划分 | 按文件清理 | 精确控制不同种类数据的清理时间 | 新增输出后需要及时更新清理任务脚本 |
删除整个目录 | 实现简单 | 需要重新拷贝运行目录 | |
按起报时间划分 | 删除整个目录 | 实现简单 | 无法精确控制不同类型数据的保留时间 |
实际业务系统往往综合使用多种方法来清理数据,需要根据每个系统的具体情况具体分析。