1. Nextflow 简介与安装

1.1 什么是 Nextflow

曾有人问我:生物信息学 pipeline 到底用什么工具写最省心?我的答案是——Nextflow。它不是第一个工作流引擎,但绝对是最懂生信工程师的那一个。

Nextflow 本质上是一个反应式工作流系统。你可以用一套脚本描述数据分析流程,然后丢给本地、集群或云端跑。它自动帮你管输入输出、任务分发、失败重试,甚至跟踪每个中间文件。说白了,你只关心三件事:输入是什么?每个步骤做什么?输出怎么组合?剩下的事,Nextflow 包了。

我个人习惯用 .nf 文件保存流程,用 DSL2 语法写模块化代码。这样每个工具封装成一个进程,清晰又好维护。

核心价值:可重复性、可扩展性、可移植性。一份 Nextflow 脚本可以不加修改地从笔记本跑上云。

1.2 核心概念

要上手 Nextflow,先搞懂三个基础概念:流程 (Workflow)、进程 (Process)、通道 (Channel)。我第一回写的时候把它们类比成工厂流水线——进程是工人,通道是传送带,流程就是整个车间管理。

1.2.1 流程 (Workflow)

流程是最高层级的编排单元。它定义过程的执行顺序以及数据如何在进程间流动。你可以理解为剧本——所有演员(进程)按剧本上台,通道就是舞台两侧的提词器。

workflow {
    // 从一个通道开始
    input_ch = Channel.fromPath('reads/*.fastq')
    // 调用两个进程,数据自动传递
    fastqc_results = FASTQC(input_ch)
    output         = TRIM_GALORE(fastqc_results)
    // 输出到文件
    output.view()
}

1.2.2 进程 (Process)

进程是具体的执行单元。它定义一个操作——比如运行一个命令、执行一个脚本。进程有明确的输入声明、输出声明,以及实际要跑的 shell 命令。

process FASTQC {
    input:
    path reads

    output:
    path 'fastqc_*'

    script:
    """
    fastqc -o . $reads
    """
}

注意看:进程的输入输出都是类型化的——path、val、tuple 等。我刚开始常把输入类型声明错,结果进程只拿到一个文件名而不是文件内容……嗯,这种坑踩一次就够了。

提示:进程可以复用。比如用 withName 给同一个进程不同阶段设置不同资源参数。

1.2.3 通道 (Channel)

通道是 Nextflow 的数据管道。它负责异步、非阻塞地传输数据。一个通道可以是一个文件、一个值、一组文件的集合。你可以用 Channel 工厂方法创建它,也可以用进程的输出直接赋值给通道。

// 创建一个值通道
ch_version = Channel.value('4.2.1')

// 创建一个文件通道
ch_reads = Channel.fromPath('/data/Sample_*.fastq.gz')

// 队列通道(每次发出一个元素)
ch_list   = Channel.of(1, 2, 3, 4, 5)

// 合并两个通道
ch_merged = ch_reads.combine(ch_version)

1.3 跨平台安装与配置

安装 Nextflow 其实很简单——依赖唯一:Java 11+(推荐 Java 17 或 21)。说说我的经历:第一次在集群上装,管理员只给了普通用户权限,我直接用 curl 下载到 ~/bin,两分钟搞定。

1.3.1 安装 Java

先确认有没有 Java:

java -version
# 如果显示版本,OK;否则:
sudo apt install openjdk-17-jdk   # Ubuntu/Debian
sudo yum install java-17-openjdk   # CentOS/RHEL
brew install openjdk@17            # macOS

1.3.2 安装 Nextflow

主流方式是用 curl 下载 wrapper 脚本,它会自动拉取最新版:

curl -s https://get.nextflow.io | bash
# 移到一个 PATH 目录下
mv nextflow ~/bin/
# 验证
nextflow info

如果你在纯离线环境,可以从 GitHub releases 下载 nextflow-XX-all jar 包,手动用 java -jar nextflow-XX-all 启动。

1.3.3 配置执行模式

Nextflow 用 配置文件(nextflow.config)控制运行环境。默认跑在本地模式,但生信 pipeline 通常需要集群或云。我一般这样配:

// nextflow.config
profiles {
    local {
        executor 'local'
        process.cpus = 4
        process.memory = '8 GB'
    }
    cluster {
        executor 'slurm'
        queueSize = 10
        process.cpus = 8
        process.memory = '16 GB'
    }
    aws {
        executor 'awsbatch'
        aws.region = 'us-west-2'
        queueSize = 100
    }
}

运行时用 -profile 参数切换:

nextflow run main.nf -profile cluster
注意:执行器选错会导致任务无法提交。我曾经把 executor 'slurm' 写成了 'local',结果一个大作业在登录节点上跑了三天……之后再也不敢马虎。

1.3.4 容器支持

Nextflow 原生支持 Docker/Singularity。设置 docker.enabled = true 后,每个进程可以在隔离容器里跑,环境完全可控:

process {
    docker.enabled = true
    container 'quay.io/biocontainers/fastqc:0.11.9--0'
}

我个人强烈建议 pipeline 里所有工具都配好容器,这样别人拿到你的代码可以直接跑,不会遇到版本冲突。

1.4 本章知识结构

下面的图总结了 Nextflow 的核心组件关系,方便你快速回顾:

Nextflow 核心概念关系图 Workflow (流程) Process (进程) Channel (通道) 编排 定义数据源 输入/输出 说明: • Workflow 调度 Process,Process 之间通过 Channel 交换数据。 • 每个 Process 可以有多个输入/输出 Channel。 • Channel 可以合并、过滤、分割,实现复杂数据流。

1.5 环境验证与第一个 Hello World

安装完毕后,运行一个最简单的流程确认环境正常:

// hello.nf
process sayHello {
    input:
    val x

    output:
    stdout

    script:
    """
    echo "Hello $x!"
    """
}

workflow {
    greetings = Channel.of('World', 'Nextflow', 'Bioinformatics')
    sayHello(greetings).view()
}
nextflow run hello.nf
# 输出:
# Hello World!
# Hello Nextflow!
# Hello Bioinformatics!

看到三行输出,恭喜你,环境没问题了。我印象特别深,2018 年第一次在 HPC 上用 Nextflow 跑变异检测流程,启动命令打下去,看着任务一个个提交到 slurm 队列,感觉像是打开了新世界的大门。

1.6 避坑指南

  • Java 版本太低: Nextflow 22+ 需要 Java 11 以上。如果你在老旧 CentOS 上,建议用 sdk install java 管理多版本。
  • PATH 没添加: 下载的 nextflow 脚本路径别忘了加到 ~/.bashrc。不然每次都要 ./nextflow。
  • 代理限制: 有些公司内网拉取不到 GitHub 资源。可以设置 export NXF_HOME=/work/nextflow 并在 ~/.nextflow/config 中配好代理。
  • 容器引擎冲突: 如果同时装了 Docker 和 Singularity,默认会走 Docker。我建议在配置里显式指定 singularity.enabled = true 避免意外。
总结一句话: Nextflow 让你用声明式的方式描述分析流程,通道负责数据传输,进程负责计算。简单、优雅、可复用。装好 Java 和 Nextflow,你已经成功了一半。