概述
您可以通过配置文件或Java命令行来配置Cromwell设置。
查看教程如何配置Cromwell获取更多信息。
配置示例
您可以在Cromwell示例配置中找到选项说明和示例配置段落,并在示例提供者文件夹中查看后端提供者示例。
自定义配置文件
您使用HOCON编写配置文件。
要使用您的配置文件运行,您应该从cromwell.examples.conf中复制相关配置段到一个新文件中,根据需要进行修改,然后通过以下方式将其传递给Cromwell:
$ java -Dconfig.file=/path/to/yourOverrides.conf cromwell.jar ...
要创建您自己的配置文件,首先新建一个文本文件,例如 my.conf。
在文件开头,请将application.conf文件包含在自定义配置之前。
# include the application.conf at the top
include required(classpath("application"))
从这里开始,复制或添加其他配置值和/或带有自定义设置的节。
# include the application.conf at the top
include required(classpath("application"))
# Add customizations
webservice.port = 58000
您的配置文件可以指定类似JSON格式的配置节或点分隔值。以下两个示例是等效的。
类JSON格式段落:
include required(classpath("application"))
webservice {
port = 8000
interface = 0.0.0.0
}
点分隔的值:
include required(classpath("application"))
webservice.port = 8000
webservice.interface = 0.0.0.0
通过命令行配置
除了使用配置文件外,您还可以使用点分隔的配置名称直接在Java命令行上指定值:
$ java -Dwebservice.port=8080 cromwell.jar ...
高级配置
警告: 这些高级配置值可能会显著影响Cromwell的性能。
服务器
默认情况下,Cromwell服务器会绑定到0.0.0.0的8000端口。
然后您可以通过浏览器访问http://localhost:8000。
要修改这些设置,只需在配置文件中编辑以下值:
webservice {
port = 9000
interface = 0.0.0.0
}
上述配置将使用端口 9000。
Cromwell使用akka-http来处理请求。如需更高级的配置设置,请参阅akka-http文档。
例如,要将请求超时时间增加到30秒,您可以在配置文件中添加以下段落:
akka.http.server.request-timeout = 30s
输入/输出
I/O 节流
某些后端会施加I/O限制。例如Pipelines API对每秒可执行的查询数量设置了配额。
您可以在system.io配置中有效控制和限制分配给这些操作的请求数量和资源:
system.io {
number-of-requests = 100000
per = 100 seconds
}
I/O 弹性
I/O操作可能因多种原因失败,从网络故障到服务器错误。其中一些错误并非致命性的,可以重试。
Cromwell会在遇到此类可重试错误时重试I/O操作,在放弃并失败前会尝试有限次数。可以通过以下配置选项设置这个次数(更准确地说,是将会进行的尝试次数):
system.io {
number-of-attempts = 5
}
工作流
最大并发工作流数
Cromwell对同时运行的工作流数量设有可配置的上限。您可以通过以下设置将默认限制从5000进行调整:
system.max-concurrent-workflows = 5000
新工作流轮询速率
Cromwell会定期查找要启动的新工作流,该间隔以秒数配置。您可以通过修改以下值来更改默认的20秒轮询频率:
system.new-workflow-poll-rate = 20
最大工作流启动次数
每次轮询时,只要有待启动的新工作流且未达到system.max-concurrent-workflows数值上限,Cromwell都会接收有限数量的新提交项。默认情况下最多启动1个工作流,您可以通过以下设置覆盖该默认值:
system.max-workflow-launch-count = 1
中止配置
Cromwell将使用与以下默认配置值等效的设置扫描中止请求。在大多数情况下,无需覆盖这些默认值。
system {
abort {
# How frequently Cromwell should scan for aborts.
scan-frequency: 30 seconds
# The cache of in-progress aborts. Cromwell will add entries to this cache once a WorkflowActor has been messaged to abort.
# If on the next scan an 'Aborting' status is found for a workflow that has an entry in this cache, Cromwell will not ask
# the associated WorkflowActor to abort again.
cache {
# Guava cache concurrency.
concurrency: 1
# How long entries in the cache should live from the time they are added to the cache.
ttl: 20 minutes
# Maximum number of entries in the cache.
size: 100000
}
}
}
数据库
使用MySQL数据库
Cromwell跟踪工作流的执行情况,并将任务调用的输出存储在SQL数据库中。Cromwell支持外部MySQL数据库或临时内存数据库。
默认情况下,Cromwell使用内存数据库,该数据库仅在JVM运行期间存在。这提供了一种在本地快速运行工作流的方式,无需设置MySQL,但这也使得工作流执行具有一定临时性。
要将Cromwell配置为指向MySQL数据库,首先需要创建一个空数据库。在下面的示例中,数据库名称为cromwell。
然后,按如下方式编辑配置文件中的 database 段落:
database {
profile = "slick.jdbc.MySQLProfile$"
db {
driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://host/cromwell?rewriteBatchedStatements=true"
user = "user"
password = "pass"
connectionTimeout = 5000
}
}
注意:Cromwell 支持 MySQL 8.0 和 8.4 版本。
Cromwell 计划支持所有当前维护的LTS版本。
要查看db配置段所有可能的参数和值,请参阅slick文档。
基于MySQL数据库的Cromwell服务器
您可以使用docker-compose将Cromwell的Docker镜像(通过sbt docker本地构建或从Dockerhub获取)与MySQL的Docker镜像进行关联。
要更改使用的Cromwell版本,修改compose/cromwell/Dockerfile中的标签。
本地
从该目录运行docker-compose up将启动一个运行在MySQL实例上的Cromwell服务器,并使用本地后端。
使用的默认配置文件可以在compose/cromwell/app-config/application.conf找到。
要覆盖它,只需将包含自定义application.conf的卷挂载到/app-config目录(参考jes-cromwell/docker-compose.yml中的示例)。
谷歌云
jes-cromwell目录展示了如何通过配置文件和环境变量来自定义原始compose文件的示例。
它使用主机上的应用程序默认凭据。要使用它,请确保您的gcloud是最新的,并且您的application-default credentials已设置好。
然后运行 docker-compose -f docker-compose.yml -f jes-cromwell/docker-compose.yml up 以启动一个基于MySQL数据库、使用Google Cloud后端的Cromwell服务器。
MySQL
MySQL容器中的数据目录挂载到compose/mysql/data,这样数据在docker-compose down后仍能保留。
要禁用此功能,只需移除volume section of docker-compose.yml中的./compose/mysql/data:/var/lib/mysql这一行。
请注意,在这种情况下,数据仍会通过docker-compose stop命令保留,该命令会停止容器但不会删除它。
注意事项
要在后台运行Cromwell,请在命令末尾添加-d:
docker-compose up -d。
要查看特定服务的日志,请运行 docker-compose logs -f 。
例如 docker-compose logs -f cromwell。
有关docker compose的更多信息:Docker compose doc。
插入批次大小
Cromwell会将记录排队然后批量插入数据库以提高性能。您可以通过以下方式调整Cromwell批量插入的数据库行数:
database {
insert-batch-size = 2000
}
独立的元数据库
此功能应被视为实验性,未来可能会发生变化。
Cromwell存储了每个作业和工作流的元数据。这些元数据面向终端用户,包含作业结果的路径、开始和结束时间等信息。元数据的增长速度远快于引擎内部其他数据。
要为元数据使用单独的数据库,请在database配置部分下,为metadata配置带有自定义设置的子路径。
database {
# Store metadata in a file on disk that can grow much larger than RAM limits.
metadata {
profile = "slick.jdbc.HsqldbProfile$"
db {
driver = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:file:metadata-db-file-path;shutdown=false;hsqldb.tx=mvcc"
connectionTimeout = 3000
}
}
}
如果没有找到metadata的覆盖配置,Cromwell将回退使用根database配置下的设置。
数据库时区
Cromwell的默认配置假定其MySQL数据库设置为UTC时区。
以下MySQL配置通常默认为UTC时区,可直接与Cromwell配合使用: - Google CloudSQL - Docker中运行的官方MySQL镜像
这些配置可能会使用系统或本地时区替代: - 原生安装在工作站或服务器上的MySQL
如果Cromwell启动失败并显示类似以下消息
The server time zone value 'XXX' is unrecognized or represents more than one time zone.
你可以通过在数据库连接URL中添加选项&serverTimezone=UTC来解决这个问题:
url = "jdbc:mysql://host/cromwell?rewriteBatchedStatements=true&serverTimezone=UTC"
使用此选项不会改变数据库的底层时区;相反,它会使Cromwell在与数据库通信时"使用UTC时间",由数据库服务器为您执行时区转换。
在Postgresql中使用Cromwell
要使用Postgresql作为数据库,您需要安装并启用大对象扩展。如果该扩展已存在,只需执行以下命令即可完成数据库设置:
$ createdb cromwell
$ psql -d cromwell -c "create extension lo;"
Cromwell中的Postgresql配置与MySQL非常相似。示例:
database {
profile = "slick.jdbc.PostgresProfile$"
db {
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost:5432/cromwell"
user = "user"
password = "pass"
port = 5432
connectionTimeout = 5000
}
}
如果您希望多个数据库用户能够从Postgresql数据库中读取Cromwell的数据,您需要创建一个所有相关用户都能访问的角色,并调整Cromwell以使用此角色。这是因为每个大型对象都由写入它的角色拥有,并且只能由该角色读取。
首先,在执行Cromwell时传递以下选项。这些选项将确保Cromwell的数据库表由角色拥有,而非初始登录用户。
* -DengineSharedCromwellDbRole=your_role 用于控制拥有引擎表的角色
* -DsharedCromwellDbRole=your_role 用于控制拥有元数据表的角色
接下来,使用配置键pgLargeObjectWriteRole设置应拥有所有大对象的角色,如下所示。
如果您未使用Postgresql,此配置将不会生效。配置的登录用户可以是任何被授予共享角色的用户。
database {
profile = "slick.jdbc.PostgresProfile$"
pgLargeObjectWriteRole = "your_role"
db {
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost:5432/cromwell"
user = "user"
password = "pass"
port = 5432
connectionTimeout = 5000
}
}
使用基于文件的数据库运行Cromwell(无需服务器)
目前不支持SQLite。不过,HSQLDB支持使用持久化文件运行。 可通过以下配置进行设置:
database {
profile = "slick.jdbc.HsqldbProfile$"
db {
driver = "org.hsqldb.jdbcDriver"
url = """
jdbc:hsqldb:file:cromwell-executions/cromwell-db/cromwell-db;
shutdown=false;
hsqldb.default_table_type=cached;hsqldb.tx=mvcc;
hsqldb.result_max_memory_rows=10000;
hsqldb.large_data=true;
hsqldb.applog=1;
hsqldb.lob_compressed=true;
hsqldb.script_format=3
"""
connectionTimeout = 120000
numThreads = 1
}
}
Explanation of the options (see also http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html):
jdbc:hsqldb:file:cromwell-executions/cromwell-db/cromwell-db;这将确保所有持久化文件最终都会存放在cromwell-executions内的cromwell-db文件夹中。shutdown=false. 这确保数据库不会被关闭,除非Cromwell明确执行关闭操作。hsqlldb.default_table_type=cached。默认情况下hsqldb使用内存表,这将确保数据写入磁盘并减少内存使用。hsqldb.result_max_memory_rows=10000. 限制临时表在内存中的行数。hsqldb.tx=mvcc这是使用hsqldb运行时的cromwell默认设置。hsqldb.large_data=true. Cromwell会创建需要打开的大型数据库。hsqldb.applog=1. 记录与数据库相关的错误。hsqldb.lob_compressed=true. 压缩大对象数据。这可以节省一些空间。需要注意的是,大对象是单独压缩的。由于许多大对象数据会相似,整个数据库仍然会包含大量冗余。hsqldb.script_format=3. 压缩脚本(内部使用gzip)。解压后仍可正常打开。connectionTimeout = 120000当运行cromwell时再次打开大型数据库文件需要一定时间。默认的超时设置3000毫秒(3秒)不够用,因此设置为120000毫秒(120秒)。numThreads = 1. 这将限制Cromwell的CPU使用率,在高性能计算环境中非常有用。
与MySQL(或PostgreSQL)服务器对比: 优势:
- 无需搭建服务器
- 无需担心数据库用户、密码和权限问题。这些将由文件系统权限处理。
缺点:
- Cromwell需要更多内存
- 数据库文件将占用大量磁盘空间(数GB的情况并不罕见)
- Cromwell与数据库的交互速度较慢。
与默认内存数据库的对比: 优势:
- 所需内存大幅减少。
- 启用调用缓存
缺点:
- 较慢。
中止
Control-C (SIGINT) 中止处理器
对于支持中止作业的后端,可以配置Cromwell在收到Control-C(也称为SIGINT)时自动尝试中止所有调用。所有当前正在运行的调用也会将其状态设置为Aborted。
要明确开启或关闭此功能,请设置配置选项:
system {
abort-jobs-on-terminate=true
}
或者,通过命令行选项 -Dsystem.abort-jobs-on-terminate=true。
默认情况下,运行java -jar cromwell.jar server时该值为false,而运行java -jar cromwell.jar run 时为true。
阅读中止部分了解更多关于中止操作的工作原理。
调用缓存
调用缓存功能使Cromwell能够检测过去是否运行过某个作业,从而避免重复计算结果。
了解更多请参阅Call Caching。
要启用调用缓存,请将以下内容添加到您的Cromwell配置中:
call-caching {
enabled = true
invalidate-bad-cache-results = true
}
当call-caching.enabled=true(默认值:false)时,Cromwell将能够引用或复制之前运行作业的结果(在适当情况下)。
当invalidate-bad-cache-results=true(默认值:true)时,Cromwell将使任何包含无法在缓存命中时访问的文件的缓存结果失效。这通常是期望的行为,但如果由于外部原因(例如用户认证差异)导致此失败,则可能不需要此行为。
Cromwell也接受工作流选项来覆盖缓存的读写行为。
文件哈希策略选项
在判断作业是否已运行时,Cromwell会获取作业输入文件的哈希值以比较文件内容。用户可以配置用于哈希文件的算法。该配置针对每个后端及其支持的文件系统单独设置,可用选项根据后端是本地还是基于云而有所不同。
配置应添加到后端的config部分:
backend {
providers {
GcpBatch {
config {
filesystems {
gcs {
caching {
hashing-strategy = ["md5", "identity"]
}
}
drs {
caching {
hashing-strategy = "crc32c"
}
}
}
}
}
Local {
config {
filesystems {
local {
caching {
hashing-strategy = "md5"
}
}
}
}
}
}
}
云存储的调用缓存策略选项
Cromwell支持配置一种或多种云文件哈希策略。如果提供了策略列表,Cromwell将按顺序尝试每种算法,直到找到可用的哈希值。该功能旨在支持不保证具有单一哈希类型的文件。Cromwell永远不会为了计算哈希值而下载文件,所有云哈希策略都依赖于文件元数据。
每个文件系统支持有限的哈希策略集。
* gcs Google存储支持:
* crc32c 默认值,保证存在
* md5 对于通过分段上传创建的文件将不存在(Cromwell本身不使用分段上传)
* identity 使用存储桶名称、blob名称和生成号来唯一标识存储对象。这比通常用于调用缓存的要求更严格 - 当使用identity时,Cromwell不会在仅输入文件内容相同的任务之间进行调用缓存,输入必须是完全相同的GS对象。这可能会破坏使用中间文件作为输入的任务的调用缓存。
* s3 AWS S3支持:
* etag 默认值,保证存在
* drs 数据存储服务支持:
* crc32c
* md5
* etag
* sha256
* 鉴于DRS数据集的多样性,无法保证所有文件都存在哈希值。DRS的默认哈希策略是["crc32c", "md5", "sha256", "etag"]
关于GCS哈希策略的说明
对于某些需要运行大量相同任务副本(仅输入文件不同)的高通量生产用例,crc32c的哈希冲突率可能高得难以接受。为了在减少可调用缓存任务集合的代价下显著降低碰撞概率,我们推荐使用hashing-strategy: ["md5", "identity"]。该策略会在MD5哈希存在时使用md5算法,否则回退到极其严格的identity策略(例如通过分段上传创建的文件)。由于Cromwell创建的所有GCS文件都保证具有md5值,identity策略仅对用户提供的工作流输入文件生效。
本地文件系统的调用缓存策略选项
Cromwell支持为本地文件哈希配置单一策略。如果未提供配置,将默认使用md5。有关与此设置交互的其他配置,请参阅下方的本地文件系统选项。
- hash based options. These read the entire file. These strategies work with containers.
xxh64(社区支持*)。该算法采用xxHash的64位实现版本,专为文件完整性哈希优化,相比md5可提供超过10倍的性能提升。md5. 知名的md5sum算法
- Path based options. These are based on filepath. Extremely lightweight, but only work with the
soft-linkfile caching strategy and can therefore do not work with containers by default.path生成路径的MD5哈希值。path+modtime会基于路径及其修改时间生成一个md5哈希值。
- Fingerprinting. This strategy works with containers.
fingerprint(社区支持)尝试通过获取文件的最后修改时间(自纪元起的毫秒数,十六进制表示)+ 大小(字节数,十六进制表示)+ 文件前10 MB的xxh64校验和来为每个文件创建指纹*。相比基于哈希的选项,这种方法更加轻量级,同时仍具有足够的唯一性,不太可能发生冲突。该策略适用于生成多GB大小文件的工作流,且在cromwell实例上对这些文件进行哈希处理会导致CPU或I/O问题的情况。 注意:此策略需要将硬链接作为复制策略,因为复制会更改最后修改时间。
(*) fingerprint 和 xxh64 策略是由Cromwell的HPC社区支持的功能。核心Cromwell团队不提供官方支持。
(**) 此值可配置,详见下文。
本地文件系统选项
在配置(共享文件系统)后端上运行作业时,Cromwell在后端的配置部分提供了一些额外选项:
config {
filesystems {
local {
# When localizing a file, what type of file duplication should occur.
# possible values: "hard-link", "soft-link", "copy", "cached-copy".
# For more information check: https://cromwell.readthedocs.io/en/stable/backends/HPC/#shared-filesystem
localization: [
"hard-link", "soft-link", "copy"
]
caching {
# When copying a cached result, what type of file duplication should occur.
# possible values: "hard-link", "soft-link", "copy", "cached-copy".
# For more information check: https://cromwell.readthedocs.io/en/stable/backends/HPC/#shared-filesystem
# Attempted in the order listed below:
duplication-strategy: [
"hard-link", "soft-link", "copy"
]
# Possible values: md5, xxh64, fingerprint, path, path+modtime
# For extended explanation check: https://cromwell.readthedocs.io/en/stable/Configuring/#call-caching
# "md5" will compute an md5 hash of the file content.
# "xxh64" will compute an xxh64 hash of the file content. Much faster than md5
# "fingerprint" will take last modified time, size and hash the first 10 mb with xxh64 to create a file fingerprint.
# This strategy will only be effective if the duplication-strategy (above) is set to "hard-link", as copying changes the last modified time.
# "path" will compute an md5 hash of the file path. This strategy will only be effective if the duplication-strategy (above) is set to "soft-link",
# in order to allow for the original file path to be hashed.
# "path+modtime" will compute an md5 hash of the file path and the last modified time. The same conditions as for "path" apply here.
# Default: "md5"
hashing-strategy: "md5"
# When the 'fingerprint' strategy is used set how much of the beginning of the file is read as fingerprint.
# If the file is smaller than this size the entire file will be read.
# Default: 10485760 (10MB).
fingerprint-size: 10485760
# When true, will check if a sibling file with the same name and the .md5 extension exists, and if it does, use the content of this file as a hash.
# If false or the md5 does not exist, will proceed with the above-defined hashing strategy.
# Default: false
check-sibling-md5: false
}
}
}
}
工作流日志目录
要更改Cromwell写入工作流日志的目录,请通过以下设置修改目录位置:
workflow-options {
workflow-log-dir = "cromwell-workflow-logs"
}
保留工作流日志
默认情况下,Cromwell会在工作流完成后删除每个工作流的日志以减少磁盘使用。您可以通过将以下值设置为false来更改此行为:
workflow-options {
workflow-log-temporary = true
}
通过Sentry进行异常监控
Cromwell支持Sentry,这是一项可用于监控应用程序日志中异常报告的服务。
要在Cromwell中启用Sentry监控,请使用系统属性输入您的DSN URL:
sentry.dsn=DSN_URL
作业Shell配置
Cromwell 允许在系统范围或每个后端作业中配置自定义shell来运行用户命令,而非始终使用默认的 /bin/bash。要在系统范围内设置作业shell,请使用配置键 system.job-shell;若需针对特定后端设置,则使用 。例如:
# 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
对于配置后端,作业shell的值将在${job_shell}变量中可用。请参阅Cromwell的reference.conf以了解如何将其用于Local后端的默认配置示例。
工作流心跳
Cromwell ID
每个Cromwell实例都会被分配一个cromwell_id。默认情况下,Cromwell ID的格式为cromid-<7位随机十六进制数>。
用户可以用自定义标识符替换字符串中的"cromid"部分。例如:
system {
cromwell_id = "main"
}
这将生成一个cromwell_id,格式为main-<7_digit_random_hex>。每次Cromwell重启时,ID中的随机部分会改变,但main前缀保持不变。
如果不应生成Cromwell ID的随机部分,请设置配置值:
system {
cromwell_id_random_suffix = false
}
心跳存活时间
当一个Cromwell实例开始运行或恢复工作流时,它会将上述cromwell_id与名为"心跳"的时间戳一起存储在工作流的数据库行中。随着工作流继续运行,Cromwell实例会间歇性地更新运行中工作流的心跳。如果Cromwell实例终止,在经过一定的存活时间(TTL)后,该工作流将被视为已放弃,并由另一个可用的Cromwell实例恢复执行。
通过配置值调整心跳TTL:
system.workflow-heartbeats {
ttl = 10 minutes
}
默认TTL为10分钟。TTL选项允许设置的最短值为10秒。
心跳间隔
心跳写入的间隔可以通过以下方式调整:
system.workflow-heartbeats {
heartbeat-interval = 2 minutes
}
默认间隔为2分钟。最短间隔选项为3.333秒。间隔时间不得超过TTL。
心跳失败关机
当Cromwell在一段时间内无法写入心跳时,它将自动关闭。这段时间可以通过以下方式调整:
system.workflow-heartbeats {
write-failure-shutdown-duration = 5 minutes
}
默认关闭时长为5分钟。允许的最大关闭时长等于TTL。
心跳批处理大小
工作流心跳由Cromwell内部排队并以批次写入。当达到可配置的批次大小时,即使心跳间隔尚未结束,批次中的所有心跳也会同时写入。
此批量阈值可通过以下方式调整:
system.workflow-heartbeats {
write-batch-size = 100
}
默认批处理大小为100。
心跳阈值
Cromwell一次写入一批工作流心跳。当待写入心跳的内部队列超过可配置的阈值时,instrumentation可能会发送一个指标信号,表明心跳负载高于正常水平。
此阈值可通过以下配置值进行设置:
system.workflow-heartbeats {
write-threshold = 100
}
默认阈值为100,与心跳批处理大小的默认值相同。
YAML
最大节点数
当检测到Yaml输入中存在循环引用时,Cromwell会抛出错误。但用户仍可能构造小型无环YAML文档来消耗大量内存或CPU资源。为限制解析过程中的处理负荷,系统对每个YAML文档的解析节点数设置了上限。
此限制可通过配置值进行调整:
yaml {
max-nodes = 1000000
}
默认限制为1,000,000个节点。
最大嵌套深度
YAML嵌套的最大深度存在限制。如果您决定增加此值,可能还需要通过使用-Xss或-XX:ThreadStackSize来增加Java虚拟机的线程堆栈大小。
此限制可通过配置值进行调整:
yaml {
max-depth = 100
}
默认限制为最大嵌套深度1,000。