一、Cromwell性能瓶颈排查概述
1.1 先聊聊 Cromwell 的架构
做性能优化之前,你得知道 Cromwell 是怎么跑起来的。说白了,它就是一个工作流引擎,专门跑生物信息学、基因组学那种计算密集的 pipeline。
我个人习惯把 Cromwell 的架构拆成三层来看:
- API 层:接收你的 WDL 请求,返回状态。它用 Akka HTTP 做异步通信。
- 引擎层:核心调度逻辑。解析 WDL、拆分任务、管理依赖、决定哪个任务先跑。
- 后端层:实际干活的地方。把任务提交给本地、HPC、或者云平台(比如 Google Cloud Batch、AWS Batch)。
我遇到过不少同学,上来就盯着后端看,觉得慢就是集群慢。其实很多时候瓶颈在引擎层——任务调度太激进,或者数据库 I/O 堵死了。
关键认知:Cromwell 不是单线程执行的。它内部有很多异步队列、数据库连接池、以及后端插件。任何一个环节卡住,整个 pipeline 都会变慢。
1.2 常见的瓶颈类型
根据我的现场排查经验,性能瓶颈基本逃不出下面这几类。你想想看,是不是很眼熟?
| 瓶颈类型 | 典型表现 | 常见原因 |
|---|---|---|
| CPU 瓶颈 | Cromwell 进程 CPU 跑满,但后端任务没跑满 | WDL 拆得太细,引擎过度调度 |
| 内存瓶颈 | GC 频繁,或者 OOM 崩溃 | 数据库连接池开太大,或者工作流元数据爆炸 |
| I/O 瓶颈 | 数据库写入慢,日志轮转卡 | MySQL 没调优,或者后端文件系统磁盘吞吐不够 |
| 并发瓶颈 | 大量任务排队,后端资源空着 | Cromwell 的最大并发数配小了,或者后端插件限流 |
| 第三方依赖瓶颈 | 调用外部 API 超时,文件传输慢 | 网络延迟,或者对象存储(如 S3、GCS)的请求限制 |
嗯,这里要注意一个坑:很多所谓的“Cromwell 慢”,其实是你的后端集群本身就慢。我一开始也踩过这个坑——花了两天调 Cromwell 的线程池,最后发现是 HPC 的共享文件系统 NFS 挂了。
1.3 排查流程:一个四步法
我整理了一套自己的排查流程,几乎每次都能用。别嫌简单,照着做就行。
- 第一步:定界——先确认问题是 Cromwell 自身慢,还是后端执行慢。简单粗暴:看 Cromwell 日志里
job-polling的间隔,如果 polling 正常但任务不结束,那就是后端问题。 - 第二步:量化——用量化指标代替感觉。看 CPU、内存、数据库连接数、任务排队长度。我个人习惯拿
top和mysqladmin status先扫一遍。 - 第三步:定位——用 Cromwell 提供的 API 拿内部指标。比如
/api/engine/v1/version看版本,/api/engine/v1/stats看调度状态。再配合jstack看线程栈。 - 第四步:优化——根据上一步的结果,调整对应配置。调完重启,重新测。一次只改一个变量。
一个小技巧:我把这个四步法画成了一张流程图,每次排查前都贴屏幕上。你可以直接拿去用。
1.4 你需要准备的工具和环境
工欲善其事,必先利其器。我列个检查清单,你对照着准备好。
- Cromwell 版本:建议 ≥ 85,旧版本有内存泄漏。可以用这个命令看:
curl -s 'http://localhost:8000/api/engine/v1/version' | python3 -m json.tool
- 数据库:MySQL 8.0+,或者 MariaDB。别用 SQLite 跑生产,你会哭的。
- 后端:本地模式也行,但正式排障建议用真实集群(HPC / 云 Batch)。
- 监控:至少能看 CPU、内存、磁盘 I/O、网络。我个人习惯先装
htop和iotop。
⚠️ 避坑指南:我曾经在生产环境看到有人把 MySQL 连接池开到 200,Cromwell 直接挂了。数据库连接数不是越大越好,建议根据并发工作流数来算,一般 20~50 就够了。
1.5 一次真实的定界案例
讲个例子吧。有一次线上 Cromwell 执行一个 500 个任务的 WDL,跑了 6 个小时还没完。用户说“Cromwell 太慢了”。
我先看了眼 Cromwell 日志,发现 job-polling 每 10 秒一次,很规律。但后端任务的 wall time 很短,说明任务本身不慢。
问题出在哪?我查了 Cromwell 的 /api/engine/v1/stats,发现队列里积压了 300 多个“等待数据库写入”的任务。
降低数据库的 max_connections,同时调大了 Cromwell 的 workflow-option { write_to_cache: false }(临时关掉缓存写入),速度立刻上来了。嗯,这就是典型的 I/O 瓶颈。
核心思路:先通过日志和 API 把问题范围缩小,再针对性地调整配置。不要一上来就改几十个参数。
好了,这是第一讲。后面我们会深入每个环节的具体排查手段和优化策略。