上一篇文章,我们介绍了 run 模式,并且针对常见的分析场景 SGE & docker 介绍了基本配置文件的撰写方式,及指定配置文件进行任务投递的方法。1
java -Dconfig.file=/path/to/yourOverrides.conf cromwell.jar run pipeline.wdl -i input.json
但是其实除了后端任务调度平台的相关配置,我们也提到还有其他的一些内容比如:资源限制,调用缓存,文件系统等,我们都可以通过配置文件进行管理,今天我们来介绍一下其他的常用配置项。
文件格式
我们在之前的示例中提供了json格式的文件,但是实际上,配置文件还有其他方式提供给Cromwell, 比如下列几种格式其实是等价的:
JSON-like stanza: 类似 JSON 的节:
1 | include required(classpath("application")) |
Dot-separated values: 点分隔值:
1 | include required(classpath("application")) |
通过命令行进行配置
1 | java -Dwebservice.port=8080 Dwebservice.interface=0.0.0.0 cromwell.jar ... |
system
I/O 管理
我们的Pipelines的中会有一些任务会访问后端请求,为了保证后端服务的稳定不至于过载爆掉,我们有时候需要对API每秒可以进行的查询数施加配额。1
2
3
4
5system.io {
number-of-requests = 100000 # 设置访问请求数目
per = 100 seconds # 设置访问等待时间
number-of-attempts = 5 # 设置失败重试次数
}
工作流
除了 API 的请求,我们也许要对我们的执行任务数进行管理。
Cromwell对一次运行的工作流数量有一个可配置的上限。您可以通过设置以下设置来调整默认 5000 限制Cromwell也会以固定的时间(单位s)建个进行轮询,查看是否有新的工作流出现,默认时间时20s:Cromwell默认只会同时接受1个工作流的提交,如果需要同时启动多个工作流也可以进行设置。
1 | system.max-concurrent-workflows = 5000 #并行任务数 |
资源管理
我们进行任务投递的集群,往往是共享资源,有些时候任务紧急,也许我们可以一个人占用所有的分析资源,但是大多数情况下这可能会被公用资源的其他同学暴打一顿。所以大多时间,我们需要限制任务对资源的使用,从而让其他同学的任务也可以运行,所以在v35版本, Cromwell 提供了配置参数,让我们可以对流程调用的资源进行管理和限制。
我们可以通过 3个参数对资源调度情况进行管理。
Hog Group
对提交的不同工作流(独立的WDL)进行分组,从而帮助我们对多个不同的工作流进行分组,从而实现同一组内所有工作流程的资源管理,对整组的资源进行限制。
- 调用的所有子任务(task)都会继承主流程的
hog-group - 不同的主流程,可以划分到同一个
hog-group。每个pipeline都对应一个唯一的工作组,每个工作组可包含多个pipeline。
配置文件中指定的是关键字(wdl中赋值的信息),而不是具体分组。
Hog Factor
Hog Factor 是大于或等于 1 的整数。表示所有资源会被多少个 group 平均分配。它代表了以下两者之间的权衡:
- Cromwell可以使用所有的资源完成工作,设置 Hog Factor = 1 时。
- 为其他分组预留资源,只使用其中一部分(1/Hog Factor)资源进行分析。 Hog Factor=2,则每个分组可以使用一半的资源进行分析。
Hog Limit
Hog Limit 是 Cromwell内部计算的,每个分组所能运行的最大任务数,这部分不需要我们进行手动的配置。
示例
1 | system { |
在对应的WDL中,应该提供对应的group 关键字,如果未提供对应关键字,会使用pipeline的名称作为默认值。1
2
3{
"hogGroup": "hogGroupA"
}
为了整体保持资源在所有工作组之间的均匀分配,Cromwell在执行任务时,不同工作组间轮转的任务运行,组内按先先后顺序进行任务运行。
1 | system { |
中止任务
对于支持中止作业的后端,可以将 Cromwell 配置为在收到 Control-C(也称为 SIGINT)时自动尝试中止所有调用。所有当前正在运行的调用也会将其状态设置为 Aborted。1
2
3system {
abort-jobs-on-terminate=true
}
database
Cromwell 跟踪工作流的执行,并将任务调用的输出存储在 SQL 数据库中。默认情况下,Cromwell 使用内存数据库,该数据库仅在 JVM 期间存在。这提供了一种无需设置 MySQL 即可在本地运行工作流的快速方法,尽管它也使工作流执行有些短暂。Cromwell 也支持外部 MySQL 数据库。若要将 Cromwell 配置为指向 MySQL 数据库,请首先创建空数据库。使用Singularity 创建Mysql数据库可以参考文档Mysql服务启动-基于Singularity
在下面的示例中,数据库名称为 cromwell 。
然后,编辑配置文件 database 节,如下所示:1
2
3
4
5
6
7
8
9
10
11
12database {
profile = "slick.jdbc.MySQLProfile$"
db {
driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://host/cromwell?rewriteBatchedStatements=true"
user = "user"
password = "pass"
connectionTimeout = 5000
}
# For batch inserts the number of inserts to send to the DB at a time
insert-batch-size = 2000
}
这部分数据库除了mysql还会存在其他各类数据库的支持,因为我个人在使用过程中并没有涉及到各种不同类型的数据库需求,如果有复杂数据库配置需求,可以参考官方文档
调用缓存
调整个参数,重新分析一遍,在研究性项目和流程开发阶段不可避免的工作,这时候我们会对数据进行多次任务分析,每次都从头进行分析会带来很大的开销,所以Cromwell提供了缓存功能。Cromwell可以在以前运行的作业缓存中搜索具有完全相同的命令和完全相同的输入的作业。如果在缓存中找到以前运行的作业,Cromwell 将使用上一个作业的结果,而不是重新运行它。利用缓存默认时关闭的,为了更好的调用缓存利用以前运行的作业,最好将 Cromwell 配置为指向 MySQL 数据库,而不是默认的内存中数据库。
1 | call-caching { |
本地文件系统选项
在 Config(共享文件系统)后端运行作业时,Cromwell 在后端的 config 部分提供了一些附加选项,可以进行文件系统相关的配置。
比如使用缓存或者容器时,文件的需要调用到新的目录进行使用,这时候,我们时采用硬链接、软连接还是拷贝整个文件。以及我们在类似call-cache阶段校验文件一致性的方案。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17config {
filesystems {
local {
localization: [
"hard-link", "soft-link", "copy"
]
caching {
duplication-strategy: [
"hard-link", "soft-link", "copy"
]
hashing-strategy: "md5"
fingerprint-size: 10485760
check-sibling-md5: false
}
}
}
}
工作流日志目录
WDL 执行过程中会产生大量的工作日志,为了更好的访问和管理这些日志文件,我们可以通过 workflow-options.workflow-log-dir="target_log_dir" 设置日志保存目录,
默认情况下,工作流完成时,Cromwell 会擦除每个工作流日志,以减少磁盘使用量。我们可以通过设置 workflow-options.workflow-log-temporary = false 来保存对应的日志。
shell 配置
默认在执行工作流程时,使用的是 /bin/bash ,但是有些时候,可能我们需要使用其他的 shell 调用,那我们可以通过设置系统层面的配置键或后端对应的配置键实现,1
2
3
4
5# system-wide setting, all backends get this
-Dsystem.job-shell=/bin/sh
# override for just the Local backend
-Dbackend.providers.Local.config.job-shell=/bin/sh
流程的心跳检测
Cromwell ID
每个 Cromwell 实例都被分配了一个 cromwell_id,默认生成的格式是 cromid-<7_digit_random_hex>。如果需要,我们可以自定义标识符可以替换字符串的“cromid”部分。1
2
3system {
cromwell_id = "main" # 自定义cromwell_id前缀
}
生成id的格式会变更为 main-<7_digit_random_hex>,当然有些情况下,我们不需要生成随机后缀,也可以通过对应的配置实现。1
2
3system {
cromwell_id_random_suffix = false # 禁用cromwell_id_random_suffix
}
Heartbeat TTL
为了确保工作流正常执行,Cromwell 会以固定的时间间隔检测任务的状态,并将任务状态更新到对应的存储数据库中。以便我们确认任务状态,同时也方便任务以外中断后,通过其他的方式进行恢复。
这部分一半采用默认配置即可,所以在此进行简单说明就不展开介绍了。
1 | system.workflow-heartbeats { |
通过这些配置,已经可以帮助我们应对大多数场景了,
reference
Cromwell ReadtheDoc SGE
Cromwell Example Backends
[https://blog.csdn.net/tanzuozhev/article/details/120629170]