说实话,第一次接触宏基因组数据的时候,看着几千万条reads完全不知道从哪下手。想知道一个样本里有哪些微生物、它们的丰度是多少,光靠比对NCBInt或者BLAST这种传统方式,一跑就是好几天,而且blast的结果处理起来也麻烦。后来同事给我推荐了Kraken2,说这个软件速度快得离谱,比对完还有Bracken做丰度校正,两条命令就能出物种组成结果。我当时半信半疑,装上之后跑了一个肠道菌群样本,几百万条reads十分钟不到就分完了,确实被惊到了。
这个组合现在是宏基因组物种注释领域的标配工具,也是大多数生信流程的首选方案。Kraken2负责把测序reads快速分类到物种分类学节点上,Bracken则在其基础上估计每个物种的真实丰度。整套流程对新手非常友好,安装不复杂,使用命令也不多,最关键的是运行速度快,普通服务器就能跑。这篇文章就围绕安装与使用这条主线,把我从零开始踩过的坑、调过的参数、看过的文档,系统整理一遍,给正准备入坑的朋友一份可以直接照着做的参考。
1. 为什么是Kraken2+Bracken这对组合
1.1 物种注释到底做什么
物种注释,简单说就是拿到测序数据之后,判断每一条reads是来自哪个物种。听起来很简单,但实际操作里有两个核心难点。
第一个难点是数量。一个宏基因组样本动辄几千万条reads,每条reads要做一次序列比对,如果用传统BLAST或者Bowtie2,时间和计算资源都会爆炸。第二个难点是精度。很多微生物之间序列相似度很高,尤其在不同菌株之间,区分起来并不容易。Kraken2的核心思路不是把所有序列全部两两比对,而是先把参考基因组切碎成固定长度的短序列片段,为每个片段建立索引,计算出一个k-mer集合。然后每来一条reads,就把它也切成一堆k-mer,去索引里查这些k-mer分别落在哪些物种上,再基于所有k-mer的综合投票来确定这条reads的分类归属。
这种方式的优势在于:查询过程不需要逐步扫描数据库,只需要一次哈希查找,所以速度极快。Kraken2的分类结果还会同时给出该分类在分类学层级上的位置,从界、门、纲、目、科、属到种。
1.2 Kraken2的分类精度问题
但Kraken2有个明显的短板,它输出的只是reads被分到了哪个taxon节点上,而不是这个物种在样本里的真实丰度。举个实际例子:如果给Kraken2输入100条reads,其中80条分给了物种A,20条分给了物种B,那么Kraken2报告里写的就是A占80%、B占20%。这看上去挺合理的,但问题在于,不同物种的基因组大小差异很大。有的细菌基因组只有2Mb,有的真菌基因组有30Mb,也就是说在丰度相同的情况下,基因组大的物种自然会被分配到更多reads。另外Kraken2分类结果里还有一类特殊标记,比如一条reads同时匹配到多个物种时,它会被分配到它们共同的分类学祖先节点上,送到属甚至科这个级别,这类reads如果直接算进物种丰度,会出现虚高的问题。
这就是Bracken存在的意义。Bracken全称是Bayesian Reestimation of Abundance with KrakEN,它能利用参考数据库里各物种的k-mer分布信息,把被分配到属、科等更高级别节点上的reads重新分布到具体物种上,同时校正基因组大小带来的偏差,最终输出更接近真实情况的物种丰度表格。
1.3 在什么场景下选这对组合
Kraken2+Bracken最适合的场景是宏基因组样本的物种组成分析,典型用途有:肠道菌群研究、环境微生物多样性调查、临床样本病原体快速筛查。如果目标是分析16S扩增子数据,Kraken2也可以跑,但像QIIME2加Greengenes这类专门流程可能更适合;如果目标是做菌株级别的精细分型,那Kraken2就有些吃力了,需要用到StrainPhlAn这类工具。不过做绝大多数属种水平的组成分析,Kraken2+Bracken几乎是最省心、最高效的选项。
2. 安装之前先想清楚这三件事
2.1 硬件条件评估
安装和使用Kraken2之前,先评估一下自己的机器配置。Kraken2本身是C++写的,对CPU的利用率很高,支持多线程,一般8核16线程的服务器就够了。内存方面需要特别注意,因为k-mer索引是直接加载到内存里的,数据库大小直接决定内存需求量。
Kraken2官方提供了几种预构建数据库:
| 数据库类型 | 磁盘占用 | 内存需求 | 说明 |
|---|---|---|---|
| MiniKraken (8GB) | 约8GB | 约8GB | 小规模测试或快速预览 |
| Standard (标准库) | 约150GB | 约75GB | 常规宏基因组分析,覆盖细菌、古菌、病毒等 |
| PlusPF | 约200GB以上 | 约100GB以上 | 标准库加真菌、原生生物,使用范围更广 |
我自己第一次用的时候只准备了32GB内存的机器,跑标准库加载到一半直接OOM(内存溢出),后来换了能扩容的机器才解决。如果你用笔记本电脑跑小样本,可以先从MiniKraken库开始;如果跑正式项目,建议至少64GB内存和几百GB剩余磁盘空间。
2.2 数据库选型思路
数据库的选择直接关系到分析结果的质量,这块建议做正式分析时不要图省事。标准数据库包含细菌、古菌、病毒以及人类基因组的参考序列,覆盖宏基因组研究中最常见的微生物类群。如果样本可能含有真菌,使用PlusPF数据库更合适,它额外加入了真菌和原生生物的数据。MiniKraken数据库虽然下载快、占用小,但覆盖物种有限,不建议用于正式科研数据。
另一个容易被忽略的点是数据库版本。Kraken2官方会定期更新数据库内容,不同版本的数据库之间分类结果可能存在差异。同一项目中的所有样本务必使用同一版本的数据库,否则不同批次之间的比较会有系统误差。我自己的建议是:建库时间和版本记录下来,写论文方法学部分也得写清楚。
2.3 安装方式取舍
Kraken2和Bracken的安装方式主要有两种:conda包管理器安装和源码编译安装。conda方式最省事,几分钟装完,我推荐大多数人用。源码编译也简单,主要价值在于自定义编译参数优化性能,不过对普通用户来说收益不大。
Bracken需要注意版本匹配问题,Bracken必须和Kraken2的主版本兼容。比如Kraken2是2.x版本,Bracken也要用对应的2.x版本。如果直接用conda同时安装Kraken2和Bracken,conda会自动解决版本依赖,比较省心。
3. Kraken2与Bracken完整安装步骤记录
3.1 用conda安装Kraken2
如果你的分析环境还没有配置conda,需要先装一个Miniconda或Anaconda。安装过程不展开,直接说装好conda之后的操作。
先创建一个独立环境,避免不同软件依赖互相干扰:
conda create -n kraken2_env python=3.8 conda activate kraken2_env然后安装Kraken2:
conda install -c bioconda kraken2装完验证一下:
kraken2 --version正常情况下会输出类似Kraken version 2.1.3这样的信息。如果提示找不到命令,检查一下环境是否激活,或者用which kraken2看看安装路径。
3.2 源码编译方式安装
源码方式适合没有conda或需要自定义优化的场景。先下载源码:
git clone https://github.com/DerrickWood/kraken2.git cd kraken2 ./install_kraken2.sh /path/to/install/directory脚本执行完后,Kraken2会安装到指定目录下的bin文件夹里。为了使用方便,把bin目录加入环境变量:
echo 'export PATH="/path/to/install/directory/bin:$PATH"' >> ~/.bashrc source ~/.bashrc源码编译的好处是可以指定编译参数,比如启用某些CPU指令集优化,但对绝大多数流程影响不大,我平时还是用conda版本。
3.3 安装Bracken
Bracken的官方GitHub仓库是jeniferjs/bracken。conda安装最简单:
conda install -c bioconda bracken装完检查:
bracken -v输出版本号说明安装成功。
源码安装也简单:
git clone https://github.com/jeniferjs/bracken.git cd bracken chmod +x install_bracken.sh ./install_bracken.shBracken安装完成后,bin目录下会生成几个脚本:bracken、bracken-build、est_abundance.py等。bracken-build这个脚本是用来为Kraken2数据库构建丰度分布文件的,后面建库时要用到,所以路径一定要记清楚。
3.4 快速验证安装是否可用
安装完成后,最稳妥的方式是跑一个最小测试。先下载MiniKraken数据库试跑一下,或者用自带的测试数据。Kraken2源码目录里通常有一个example文件夹,里面放了示例数据。
kraken2 --db minikraken_db_v2 --threads 4 example.fa能正常输出分类结果文件,说明整个安装链路没问题。我在第一次安装时跳过这个测试,直接跑正式数据,结果建库路径写错了,排查了半天才发现问题。装完先跑最小测试,这个习惯能省很多时间。
4. 数据库下载与构建,这里最耗时
4.1 使用官方预构建数据库
Kraken2官方提供预构建数据库,直接下载解压就能用,省去自己构建的漫长时间。下载地址在Kraken2的GitHub仓库“Database”部分有提供,或者用下面的命令从官方AWS存储拉取:
# 下载标准库(大小约150GB) wget https://genome-idx.s3.amazonaws.com/kraken/k2_standard_2023.tar.gz # 解压到指定目录 mkdir -p /path/to/kraken2_db tar -xvzf k2_standard_2023.tar.gz -C /path/to/kraken2_db下载标准库需要较长时间,网络条件差的话建议使用支持断点续传的下载工具,或者分时段下载。解压后的目录里包含hash.k2d、opts.k2d、taxo.k2d三个核心文件,还有一个seqid2taxid.map映射文件。
使用预构建数据库时,需要确保Bracken的kmer分布文件也一起下载。最新的标准库压缩包中通常已经包含了Bracken需要用的database150mers.kmer_distrib等文件。如果没有,还需要额外运行Bracken的构建步骤。有一个容易踩的坑:下载的数据库版本和Bracken的期望版本不匹配,运行bracken的时候会报错中断,所以下载时留意一下数据库自带文件的完整性。
4.2 手动构建自定义数据库
如果研究物种比较特殊,或者数据里有大量参考数据库没覆盖的物种,就需要自己构建数据库。手动构建分三步走。
第一步,下载分类学信息:
kraken2-build --download-taxonomy --db $DBNAME这里的$DBNAME是自定义的数据库目录名,要先创建好。这个命令会从NCBI下载taxdump文件,构建分类学树。
第二步,下载参考序列,按分类学组别下载细菌库:
kraken2-build --download-library bacteria --db $DBNAME可选类别包括bacteria、viral、fungi、archaea、protozoa等。如果下载中断,重新执行命令会继续下载未完成的部分。
第三步,构建k-mer数据库:
kraken2-build --build --db $DBNAME --threads 16这一步会把下载下来的参考序列切碎成k-mer并建立索引,过程非常消耗内存和CPU。标准库构建时内存不够就会直接报错,建议至少64GB。构建完成后数据库目录下会出现hash.k2d文件,就说明建好了。
4.3 为Bracken构建kmer分布文件
Bracken要想做丰度校正,必须先针对Kraken2数据库构建一个k-mer分布文件。这一步使用bracken-build脚本完成。
bracken-build -d $DBNAME -t 16 -k 35 -l 150参数解释:
-d指定数据库目录-t指定线程数-k指定k-mer长度,必须和Kraken2建库时使用的k-mer长度一致,默认是35-l指定reads长度,根据测序reads的实际长度来,一般宏基因组是150bp
构建完成后,数据库目录里会出现类似kmer_distrib_150的文件。
Bracken构建过程会先对数据库里的参考序列重新做一次Kraken2分类,生成所有物种的k-mer分布信息,这个过程同样需要较长时间,建议后台运行并记录日志。
nohup bracken-build -d $DBNAME -t 16 -k 35 -l 150 > bracken_build.log 2>&1 &期间用tail -f bracken_build.log观察进度。构建失败时日志里会有明确报错信息,最常见的是Kraken2版本不兼容,报错内容类似于Unknown kraken2 database format,这时候要检查Kraken2版本是否太旧,Bracken要求2.0.7以上。
4.4 数据库管理的几个习惯
Kraken2数据库文件很大,管理不好容易出问题。先说磁盘规划,预构建库解压时需要的临时空间差不多是压缩包两倍大小,比如150GB的压缩包解压时需要预留300GB以上空间。其次,数据库路径建议用固定目录,并把路径写入环境变量或者分析流程配置里,避免每次运行命令时手写路径出现差错。最后,不同版本的数据库不要放在同一个目录里,命名时带上版本号,比如k2_standard_2023这样的命名,时间久了也不容易搞混。
5. 实战:完整跑通一个Kraken2+Bracken分析
5.1 准备工作与测试数据
为了演示完整流程,我准备了一份模拟的宏基因组双端测序数据,大约100万条reads,模拟成一个肠道菌群样本。实际操作时,可以先从SRA下载公开宏基因组数据,或者自己生成模拟数据做测试。
输入数据的格式通常是FASTQ。如果数据是原始下机数据,带有接头,建议先用fastp或Trimmomatic做质控和去接头,不要拿原始数据直接跑分类。质控干净虽然会损失一部分reads,但能减少假阳性分类。我自己的经验是,接头残留确实会导致一些reads错误地比对到人工序列上,进而影响物种注释。
准备一个样本清单文件,每个样本一行,格式为样本名加路径,方便批量处理。
5.2 Kraken2分类命令详解
Kraken2分类的标准命令:
kraken2 --db /path/to/k2_standard_2023 \ --threads 16 \ --paired \ --output sample1.kraken \ --report sample1.kraken_report \ --use-mpa-style \ sample1_R1.fastq.gz sample1_R2.fastq.gz逐项解释参数:
--db:指定数据库路径--threads:线程数,按机器配置调整,一般设为核心数的一半或全部--paired:输入为双端reads,此模式下两条reads都匹配到同一物种才算数--output:分类结果输出文件,每行一条reads,格式为“分类状态 taxid readID 序列 分类路径”--report:汇总报告文件,展示每个taxon的reads数和比例--use-mpa-style:以MPA样式输出报告,便于后续合并多个样本
运行结束后,sample1.kraken_report的文件内容类似:
94.32 943201 943201 U 0 unclassified 5.68 56782 45210 R 1 root 5.68 56782 0 R1 131567 cellular organisms ...第一列是比例,第二列是该分类及其子分类覆盖的reads总数,第三列是该分类本身直接分配的reads数,第四列是分类学级别(U表示未分类、R表示根节点、G表示属、S表示种)。
--use-mpa-style生成的报告格式有些不同,更适合下游合并和热图可视化。如果只跑一个样本,两种格式差别不大;如果跑多个样本要合并成丰度表,MPA格式会更方便。
5.3 Bracken丰度校正命令详解
得到Kraken2报告文件后,接下来用Bracken做丰度重估。运行前先确定目标分类层级。通常分析物种组成用种水平,命令如下:
bracken -d /path/to/k2_standard_2023 \ -i sample1.kraken_report \ -o sample1.bracken \ -r 150 \ -l S \ -t 16参数解释:
-d:数据库目录-i:输入Kraken2报告文件-o:输出Bracken丰度结果-r:reads长度,必须与构建Bracken kmer分布时设置的-l一致-l:分类层级,S表示种(Species),G表示属(Genus)-t:线程数
Bracken运行完成后会生成两个文件:sample1.bracken是最终的丰度估算文件,另一个是sample1.bracken_report,后期可视化常用到的就是后一个。
看一个输出片段示例:
name taxonomy_id taxonomy_lvl kraken_assigned_reads added_reads new_est_reads fraction_total_reads Escherichia coli 562 S 12000 3500 15500 0.1123 Bacteroides vulgatus 821 S 8000 1200 9200 0.0667每一行代表一个物种,重点是new_est_reads和fraction_total_reads这两列,前者是该物种校正后的reads数,后者是该物种在样本中的相对丰度。把fraction_total_reads加总,就能得到完整的物种组成谱。
5.4 多样本批量处理与合并
实际项目中很少只测一个样本,几十个样本批量跑时,需要对处理流程做点小小优化,比如用循环把每个样本提交给后台任务执行。
先写一个Shell循环分别对每个样本运行Kraken2和Bracken,为了不让流程卡在单条命令上,后台任务加日志记录:
for sample in sample1 sample2 sample3; do kraken2 --db /path/to/k2_standard_2023 \ --threads 8 \ --paired \ --output ${sample}.kraken \ --report ${sample}.kraken_report \ ${sample}_R1.fastq.gz ${sample}_R2.fastq.gz & done全部跑完后,用KrakenTools里的combine_kreports.py脚本把多个Kraken2报告合并成一个表,生成以分类学单元为行、样本为列的丰度矩阵。
combine_kreports.py --report sample1.kraken_report sample2.kraken_report sample3.kraken_report --output combined_report.tsvcombined_report.tsv就是下游做热图、PCoA、差异分析的标准输入表格。这里列一下KrakenTools的安装方式,它是个Python工具包,直接从GitHub拉下来就能用,不依赖额外的包:
git clone https://github.com/jenniferlu717/KrakenTools.git对丰度表做后续分析时,我一般先用vegan包或phyloseq包做多样性分析,再用ggplot2画堆叠柱状图展示物种组成。这一步已经跨入统计可视化范畴,不做展开,提醒一点:Bracken输出的丰度是相对丰度,做差异比较时需要考虑闭合效应,必要时转成绝对丰度或者用ALDEx2这类专门工具。
6. 常见问题排查与经验技巧
6.1 运行过程中的典型报错
把这一年多被问得最多的问题和解决思路整理成一个速查表:
| 报错信息 | 可能原因 | 解决办法 |
|---|---|---|
Error: Unable to open database | 数据库路径错误或文件损坏 | 检查路径、重新解压数据库 |
Out of memory | 内存不足,数据库加载失败 | 换大内存机器,或用MiniKraken |
k-mer file hash.k2d not found | 数据库不完整 | 确认构建步骤完成,hash.k2d必须存在 |
Bracken: Error reading distribution file | Bracken的kmer分布文件未构建或不匹配 | 运行bracken-build生成对应reads长度的分布文件 |
Unknown kraken2 database format | Kraken2版本过旧 | 升级Kraken2到2.0.7以上 |
Cannot open taxo.k2d | 数据库目录结构不全 | 重新下载taxo.k2d文件 |
6.2 运行速度的调优思路
Kraken2的运行速度受三个因素影响:CPU线程数、数据库类型、输入文件大小。线程数上来之后速度提升明显,但也不是无限制增长,一般16核以内线性扩展还行,再往上提升就变缓了。磁盘IO也是一个影响点,机械硬盘跑大型数据库时启动阶段会明显偏慢,有条件用SSD能省不少时间。
输入文件建议用压缩格式FASTQ.GZ直接输入,Kraken2支持自动解压,不用手动解压,可以省下大量临时磁盘空间和IO时间。我第一次跑的时候为了保险把数据都解压成了明文的fastq,白白占了三倍磁盘空间,后续发现直接喂压缩文件完全没问题。
6.3 Bracken分类层级选择的细节
Bracken默认支持从域到种多个层级,实际分析中物种水平(-l S)用得最多,属水平(-l G)次之。做物种水平分析时要注意,参考数据库里有些条目标注不完整,比如某些菌株在NCBI的分类学树里只定位到属,这时Bracken无法把reads校正到种,只能归到上一级,结果里就会出现“Genus”和“Species”混着的情况。处理这种结果时,可以把不同分类层级分开看,或者用物种注释工具提供的分类学过滤器过滤过低支持度的分类。
6.4 踩过几次坑之后的几点心得
首先,数据库下载别图快,官方标准库最好下完整包,只用一部分参考序列建库看起来省了时间,实际跑出来的结果覆盖度差很多。其次,跑正式数据前一定先用小规模测试数据验证流程。最后,做好数据库版本记录。同一项目里用不同版本的数据库,结果不一致是一个很尴尬的问题,尤其投稿返修时,审稿人问起物种注释版本,如果拿不出记录,会非常被动。
另外分享一个日常小技巧:写分析流程时把Kraken2和Bracken的命令参数写进配置文件里,用Snakemake或Nextflow管理的话,每个样本的输入输出参数自动记录,这样不仅完整复现方便,出了问题排查日志也快。
Kraken2+Bracken的高效和易用,让物种注释从一个耗时的瓶颈环节变成了分析流程里最顺畅的一步。只要数据库选好、参数配好,从原始数据到物种丰度表,半天就能跑完一轮。实际使用中如果遇到数据库下载或内存不足这类问题,先按上面表格排查,大多数情况下都能解决。后面如果再深入一些,可以把Kraken2的结果和金标准比对工具做交叉验证,或者把注释结果接入功能预测流程,这些都是已经比较成熟的方向了。