GATK4.0 Spark性能分析

摘要

这篇文章讲记录GATK4.0 Spark流程之中性能点的分析.
目前我们团队已经把整个参数调优已经做到了极致, 目前已经识别的这些性能优化点只能优化GATK代码方式去调优了, 这也是我们团队接下来的一个重要工作.

因此, 这篇文章讲包括:

  1. GATK步骤的主要瓶颈点
  2. 以及造成该瓶颈的原因
  3. 优化建议

这篇文章不包括:

  1. 具体的GATK调优的参数
  2. 具体的Spark调优的参数
  3. GATK算法相关瓶颈点(目前能力不够, 以后有机会再分析)
  4. GATK源码级调优

流程剖析

之前已经有介绍GATK4.0 Spark的测序流程, 这里就按照里面的步骤一个一个分析吧.

分析的样本为NA12878的fastq.gz(98GB)文件, Ref使用HG38(3G), KnownSites使用GATK官网文件, 总大小为8G

1
2
3
4
5
6
1000g_omni2.5.hg38.vcf
1000g_phase1.snps.high_confidence.hg38.vcf
dbsnp_144.hg38.vcf
hapmap_3.3.hg38.vcf
homo_sapiens_assembly38.known_indels.vcf
mills_and_1000g_gold_standard.indels.hg38.vcf

FastqToSam

由于FastQ文件是GZ格式的, 而Gzip格式在HDFS上是无法切分的, 因此无法用Spark加速, 所以实际上FastqToSam工具是单机的.
这个步骤主要耗时是花费在fastq.gz解压缩之中, 目前我们处理这个步骤需要花费90分钟, 而使用linux的命令解压缩单个文件大约就需要1个小时以上, 因此基本上只要解压缩完就能处理完毕

现状瓶颈: fastq.gz的文件解压缩

瓶颈原因: FastqToSam调用的是Java的GZip库进行解压的, 因此整个性能和linux gzip命令的性能一样. 而gzip解压缩最大的问题在于是单线程解压的, 因此性能一直不高, 而且机器的CPU利用率也非常低.

优化建议: 实际上fastq.gz格式不是linux上那种通用的gzip格式, 而且专门为生物信息领域设计的gzip格式, 因此它实际上可以多线程解压的. 经过测试使用bgzip多线程解压, 性能可以从原有的1个小时, 提高到半个小时左右(4线程). 但是目前这个工具似乎只有C语言版本, FastqToSam是用java写的, 如果想利用这个步骤, 可能要用到JNI的技术来实现C语言的加载.

BwaSpark

首先看一样,BwaSpark的Spark的任务图

总共有2个长时间的Job组成, 一个是collect,一个是save

分析collect过程, 发现每个Task都很小, 绝大部分的时间加载Ref文件, 由于每个Executor都需要拉取5G左右的Ref文件, 当Executor达到50个以上的时候, 将近有250GB的数据需要在集群交互.

save过程, 是用BWA软件将每个小的Bam文件进行比对, 这个步骤目前无法优化.

现状瓶颈: 获取HDFS数据慢

瓶颈原因: 每个Executor都需要拉取5G左右的Ref, HDFS无法承受如此高的资源.

优化建议: 提前加载Ref的Image的数据, 让整个流程快速开始计算.

ReadsPipelineSpark

看一下, ReadsPipelineSpark的Spark的任务图

这个时间需要消耗在BaseRecalibratorSparkVariantsSparkSink,前者是BQSR的计算流程, 后者是HaplotypeCallerSpark的流程.

HaplotypeCallerSpark只消耗了32min符合预期, 但是BQSR流程耗时1.2小时, 时间慢的不正常.


打开最慢的那个步骤的日志, 发现加载KnownSites文件将近耗费了25分钟, 整个流程被阻塞近半个小时.

现状瓶颈: KnownSites文件加载过慢

瓶颈原因: 每个Exeuctor都要计算并加载整个KnownSites

优化建议: 提前加载KnownSites的数据, 让整个流程快速开始计算.

总结

目前对于Spark WGS流程的优化点, 有以下两个:

  1. 使用bgzip加速FastQ转化Bam
  2. 将整个GATK作为Service, 提前加载好所有的资源文件, 客户端提交工具请求, 服务端直接开始计算. 作为完全的Serviceless的服务.