告别磁盘告急!Apache DolphinScheduler 日志滚动与自动清理实战

📅 发布时间:2026/7/5 13:21:35 👁️ 浏览次数:
告别磁盘告急!Apache DolphinScheduler 日志滚动与自动清理实战
1. 从一次“磁盘爆满”的线上告警说起那天下午我正在悠闲地喝着咖啡突然手机开始疯狂震动一连串的告警短信涌了进来。登录服务器一看好家伙部署 Apache DolphinScheduler 的那台机器磁盘使用率已经飙到了 98%红色警报刺眼得很。赶紧df -h和du -sh命令一顿操作最终定位到元凶/opt/dolphinscheduler/logs目录足足占用了上百个 G 的空间。里面密密麻麻全是dolphinscheduler-master.2024-03-15_10.0.log、dolphinscheduler-worker.2024-03-10_14.3.log这类文件。系统还在跑着重要的生产工作流要是因为磁盘写满导致任务失败甚至服务宕机那麻烦可就大了。我相信很多运维过 DolphinScheduler 的朋友都遇到过类似的情况。这个优秀的调度系统在勤勤恳恳处理我们海量任务的同时也会忠实地记录下每一个步骤、每一次心跳、每一条 SQL 执行的痕迹。时间一长这些日志文件就像房间里无人打扫的灰尘悄无声息地占满了所有空间。手动清理太原始而且容易忘。写个脚本定期删是个办法但有点“治标不治本”而且如果删除策略和日志滚动策略没对齐可能会误删正在使用的日志。所以我们需要一套更系统、更自动化、从源头进行管理的方案。这就是今天要聊的通过配置日志滚动策略再结合操作系统的定时任务双管齐下彻底告别磁盘告急的烦恼。简单来说我们的目标是实现两点第一让单个日志文件别太大到一定尺寸就自动切分滚动第二让历史日志文件别存太久超过保留期限就自动删除。这样磁盘空间的使用就会形成一个良性的循环再也不用半夜爬起来处理告警了。2. 核心武器深入理解 Logback 的滚动策略要管理好 DolphinScheduler 的日志我们得先和它的日志框架——Logback 打好交道。DolphinScheduler 默认使用 Logback 来记录日志它的配置文件就藏在安装目录的conf/文件夹下。你会看到好几个以logback-开头的文件例如logback-master.xml、logback-worker.xml、logback-api.xml它们分别对应着 Master、Worker、Api 这几个核心服务的日志配置。打开任何一个文件你都会找到类似下面这样的配置段落这是整个日志滚动机制的核心appender nameAPILOGFILE classch.qos.logback.core.rolling.RollingFileAppender file${log.base}/dolphinscheduler-api.log/file rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy fileNamePattern${log.base}/dolphinscheduler-api.%d{yyyy-MM-dd_HH}.%i.log/fileNamePattern maxHistory168/maxHistory maxFileSize64MB/maxFileSize /rollingPolicy encoder pattern[%level] %date{yyyy-MM-dd HH:mm:ss.SSS} %logger{96}:[%line] - %msg%n/pattern charsetUTF-8/charset /encoder /appender别看这段 XML 配置有点复杂我们拆开揉碎了看就明白它怎么控制日志的生老病死了。这里定义了一个叫做RollingFileAppender的“记录器”它负责把日志写到文件里并且具备“滚动”超能力。关键就在于那个SizeAndTimeBasedRollingPolicy基于大小和时间的滚动策略它有两个黄金参数maxFileSize单个日志文件的“体重上限”。默认是64MB。意思是当一个日志文件比如dolphinscheduler-api.log写到了 64MBLogback 就会立刻把它“打包封存”然后创建一个新的、空白的dolphinscheduler-api.log继续写。被封存的文件会被重命名按照fileNamePattern的格式来。例子中的模式%d{yyyy-MM-dd_HH}.%i表示按“年月日_小时”和索引编号来命名例如dolphinscheduler-api.2024-03-20_14.0.log。maxHistory日志文件的“最长寿命”。默认是168单位是天。这意味着Logback 会尝试保留最近 168 天内的滚动日志文件那些按模式命名的文件。注意它只管理由它自己滚动产生的历史文件对于当前正在写入的主日志文件dolphinscheduler-api.log和超出这个时间范围的历史文件它就不负责主动删除了。这里有个非常重要的认知点很多人以为设置了maxHistory7系统就只会保留7天的日志。不完全对Logback 的maxHistory清理动作通常发生在日志滚动新文件创建的那一刻。如果系统近期非常空闲没有产生新日志触发滚动那么即使有些旧文件已经“过期”它们可能还会一直留在磁盘上。这就是为什么我们还需要操作系统定时任务来作为“第二道保险”。3. 实战第一步优化你的 Logback 配置文件理解了原理我们现在就来动手改造把默认的“豪放派”配置改成贴合我们实际需求的“精细派”。我个人的经验是对于生产环境保留 30 天日志通常足以应对绝大多数问题排查场景单个文件大小设置在 100MB-200MB 之间比较平衡既能减少文件数量又不会因为单个文件过大而难以打开和分析。假设我们的 DolphinScheduler 安装在/opt/dolphinscheduler我们需要修改conf/目录下的几个文件1. 修改 Master 服务日志配置 (logback-master.xml)cd /opt/dolphinscheduler/conf vim logback-master.xml找到RollingFileAppender部分修改maxHistory和maxFileSize!-- 找到类似配置段进行修改 -- rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy fileNamePattern${log.base}/dolphinscheduler-master.%d{yyyy-MM-dd}.%i.log/fileNamePattern !-- 将保留天数从168改为30 -- maxHistory30/maxHistory !-- 将单个文件大小从64MB改为100MB -- maxFileSize100MB/maxFileSize /rollingPolicy注意我在这里把fileNamePattern中的%d{yyyy-MM-dd_HH}按小时滚动改为了%d{yyyy-MM-dd}按天滚动。这对于大多数场景更合理因为按小时滚动会产生大量小文件增加文件系统管理开销。按天滚动结合文件大小限制是更常见的做法。2. 同理修改 Worker 和 API 服务的配置用同样的方法编辑logback-worker.xml和logback-api.xml将maxHistory改为30maxFileSize改为100MB。如果你的 Alert 等服务也独立部署且有日志配置也一并修改。3. 一个关键的补充配置totalSizeCap在较新版本的 Logback1.1.8中滚动策略还支持一个非常实用的参数totalSizeCap总大小上限。它可以防止历史日志文件总体积无限增长。我强烈建议你加上它rollingPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy fileNamePattern${log.base}/dolphinscheduler-master.%d{yyyy-MM-dd}.%i.log/fileNamePattern maxHistory30/maxHistory maxFileSize100MB/maxFileSize !-- 增加此行所有历史日志文件总大小不超过20GB -- totalSizeCap20GB/totalSizeCap /rollingPolicy设置了totalSizeCap后当所有历史日志文件的总大小超过 20GB 时Logback 会在触发滚动时从最旧的文件开始删除直到总大小低于这个上限。这是控制磁盘占用的一道强力防线。4. 修改完成后重启服务配置文件的修改需要重启对应的 DolphinScheduler 服务才能生效。根据你的部署方式单机、伪集群、集群执行重启命令。例如使用脚本管理的话# 在 DolphinScheduler 安装目录下 ./bin/stop-all.sh ./bin/start-all.sh重启后新的日志文件生成就会遵循你设定的新规则了。你可以观察logs/目录看看新生成的滚动日志文件是否按yyyy-MM-dd的日期格式命名。4. 实战第二步用 Crontab 设置定时清理双重保障经过上一步的配置日志的“生长”已经被控制住了。但是正如前面提到的maxHistory的清理可能不是实时的而且它不处理当前正在写入的活跃日志文件那个不带日期后缀的.log文件。为了万无一失我们还需要在操作系统层面设置一个“扫地机器人”定期清理过期文件。最经典的工具就是 Linux 的crontab定时任务。我们的思路是编写一个简单的 Shell 脚本用find命令定位并删除超过一定天数的日志文件然后让cron每天凌晨去执行这个脚本。1. 编写清理脚本我们在一个合适的位置创建脚本比如/opt/scripts/clean_ds_logs.sh#!/bin/bash # Apache DolphinScheduler 日志自动清理脚本 # 描述删除 logs 目录下修改时间超过 N 天的日志文件 # DolphinScheduler 安装目录 DS_HOME/opt/dolphinscheduler # 日志保留天数建议比 Logback 的 maxHistory 多留几天作为缓冲 RETAIN_DAYS35 # 日志目录 LOG_DIR${DS_HOME}/logs echo $(date %Y-%m-%d %H:%M:%S) 开始清理 DolphinScheduler 日志 # 清理 Master 历史日志按模式匹配 find $LOG_DIR -type f -name dolphinscheduler-master.*.log -mtime $RETAIN_DAYS -delete -print # 清理 Worker 历史日志 find $LOG_DIR -type f -name dolphinscheduler-worker.*.log -mtime $RETAIN_DAYS -delete -print # 清理 API 历史日志 find $LOG_DIR -type f -name dolphinscheduler-api.*.log -mtime $RETAIN_DAYS -delete -print # 清理 Alert 等其他服务日志根据实际情况添加 # find $LOG_DIR -type f -name dolphinscheduler-alert.*.log -mtime $RETAIN_DAYS -delete -print # 可选清理非常旧的、正在写入的当前日志文件风险较高慎用 # 如果当前日志文件超过一定大小且很久没被修改可能服务异常可以考虑清理 # find $LOG_DIR -type f -name dolphinscheduler-*.log ! -name *.log.* -mtime 60 -size 1G -delete -print echo 日志清理完成 给脚本加上执行权限chmod x /opt/scripts/clean_ds_logs.sh脚本安全提示-delete动作是直接删除非常危险。在第一次执行前强烈建议你先用-print替换-delete运行一下脚本看看它会列出哪些文件确认无误后再改为删除。你也可以将删除的文件先移动到临时目录观察一段时间后再彻底删除这样更保险。2. 配置 Crontab 定时任务使用crontab -e命令编辑当前用户的定时任务建议使用部署 DolphinScheduler 的服务账户如dolphinscheduler用户crontab -e在打开的编辑器中添加一行表示每天凌晨 3 点执行清理脚本# 每天凌晨3点执行日志清理脚本 0 3 * * * /bin/bash /opt/scripts/clean_ds_logs.sh /opt/scripts/clean_log.log 21这行配置的意思是在每天的第 0 分钟、第 3 小时即凌晨3:00执行后面的命令。 /opt/scripts/clean_log.log 21将脚本的标准输出和错误输出都重定向到一个日志文件中方便我们后续查看定时任务是否执行成功或者排查问题。3. 验证定时任务保存退出后可以通过以下命令查看已设置的定时任务crontab -l你也可以手动执行一次脚本测试其是否正确工作/opt/scripts/clean_ds_logs.sh然后检查logs/目录和输出的日志文件/opt/scripts/clean_log.log。5. 高级技巧与避坑指南做到上面两步你的磁盘空间基本就高枕无忧了。但根据我多年的实战经验还有一些细节和高级玩法能让你这套日志管理体系更加稳固和高效。1. 不同服务的日志量差异Master 和 API 服务的日志量通常相对稳定而 Worker 服务的日志量则与它执行的任务类型、数量直接相关。如果你某些 Worker 节点运行着非常密集的 Spark、Flink 或大量 Shell 任务它的日志增长速度会远快于其他服务。针对这种情况你可以采取差异化配置差异化 Logback 配置为日志量特别大的 Worker 单独调整其logback-worker.xml设置更小的maxFileSize如50MB和更短的maxHistory如15并设置一个较小的totalSizeCap如5GB。差异化清理脚本在清理脚本中为不同服务的日志设置不同的RETAIN_DAYS。例如Worker 日志保留 15 天Master 和 API 日志保留 35 天。2. 关于totalSizeCap的注意事项totalSizeCap是个好东西但要注意它的计算范围。它只统计匹配fileNamePattern的历史滚动文件不包括当前正在写入的活跃日志文件。所以你的磁盘空间规划需要把这部分“当前日志”也考虑进去。另外确保你使用的 Logback 版本支持这个特性。3. 日志清理的“安全缓冲区”在配置中我故意让操作系统的清理脚本保留天数35天比 Logback 配置的maxHistory30天要多几天。这形成了一个“安全缓冲区”。因为 Logback 的清理是事件触发滚动时而操作系统的清理是时间触发每天。两者在时间上可能不同步多保留几天可以避免在 Logback 还没来得及清理旧文件时系统定时任务就误删了还可能需要的日志。这个缓冲区的天数可以根据你对日志重要性的判断来调整。4. 监控与告警自动化之后我们还需要设置监控。除了监控磁盘使用率本身还可以监控日志清理脚本的执行情况。例如检查/opt/scripts/clean_log.log这个输出日志是否每天都有更新文件大小是否正常。你可以在脚本末尾添加一行发送一个心跳到你的监控系统或者简单地在 crontab 的邮件输出中查看。更进阶一点可以写一个监控脚本定期检查logs/目录下最老的文件日期如果发现存在远超过RETAIN_DAYS的文件就发出告警提示自动清理机制可能失效了。5. 容器化部署的特别处理如果你的 DolphinScheduler 是使用 Docker 或 Kubernetes 部署的思路一样但方法略有不同。Logback 的配置文件需要被打包进镜像或者在启动时通过卷挂载进去。而日志清理任务则更适合放在宿主机上通过cron来清理挂载到宿主机的日志卷目录。在 K8s 环境中可以考虑使用CronJob资源对象来运行一个专门负责日志清理的 Pod这个 Pod 的任务就是执行上述的清理脚本完成后退出。这样更符合云原生的管理范式。6. 效果检验与日常维护配置完成后我们怎么知道它工作得好不好呢这里有几个检验和维护的小方法。首先观察日志目录结构。定期去logs/目录下用ls -lht命令看看。健康的状态应该是有一批以日期命名的历史日志文件如dolphinscheduler-master.2024-03-10.0.log它们的日期分布大概在你设置的保留天数范围内同时每个服务都有一个最新的、正在写入的dolphinscheduler-xxx.log文件这个文件的大小应该在你设置的maxFileSize附近波动不会无限增长。其次检查磁盘空间变化。你可以写个简单的命令每天记录一下日志目录的大小# 可以将此命令也加入 crontab每天运行一次并记录结果 date /opt/scripts/log_dir_size.log du -sh /opt/dolphinscheduler/logs /opt/scripts/log_dir_size.log过一段时间你就能看到日志目录的大小稳定在一个区间内不会再出现之前那种线性增长直到撑爆磁盘的情况。最后定期审查策略。业务在发展系统的负载在变化。建议每季度或每半年回顾一下你的日志保留策略。问问自己30天的日志真的够用吗有没有因为某个偶发的复杂问题需要回溯更久的日志单个文件 100MB 在日志分析工具里打开是否流畅根据实际的运维需求和工具链微调maxHistory、maxFileSize和RETAIN_DAYS这些参数。日志管理不是一劳永逸的设置而是一个需要随业务一起成长的持续过程。经过这样一套组合拳下来我负责的几个 DolphinScheduler 集群再也没有发生过因为日志导致的磁盘告警。这套方法的核心思想其实就是“源头控制”加“定期巡检”。从日志框架层面管住它的“生长方式”和“存活周期”再从系统层面加一道保险进行“强制退休”。把这种日常运维工作自动化、规范化我们才能把更多精力放在更有价值的任务调度和业务逻辑优化上。希望这份详细的实战指南能帮你一劳永逸地解决 DolphinScheduler 的日志磁盘占用问题。