基于 Graviton2处理器构建容器化基因分析工作负载

0
0
{"value":"#### **概述**\n\n相对于基于传统 x86架构的处理器来说,Amazon 设计的基于 ARM 架构的 Graviton 处理器为 EC2中运行的云工作负载提供了更佳的性价比。基于 Graviton2 的实例支持广泛的通用型、突发型、计算优化型、内存优化型、存储优化型和加速计算型工作负载,包括应用程序服务器、微服务、高性能计算 (HPC)、基于 CPU 的[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail) (ML) 推理、视频编码、电子设计自动化、游戏、开源数据库和内存中的缓存等。由 Graviton2 处理器支持的 EC2实例 (M6g、C6g、R6g和T4g) 在中国区已经上线一段时间,本文以土壤微生物宏基因测序为例,来演示如何利用Amazon Batch 服务调用基于 Graviton2处理器的实例用于基因分析,并且验证 Graviton2相对于 x86架构的处理器能够给用户带来的收益。\n\n#### **先决条件**\n\n您需要一个 Amazon 帐户来完成本演练,其它条件包括(本篇不再描述其具体使用方式):\n\n- [Amazon CLI v2](https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/install-cliv2-linux.html)安装和配置\n- 完成 VPC 的设置,包括公有子网、私有子网和 NAT 的配置等\n- 熟悉 EC2服务的使用,熟悉 EFS、S3等存储服务的使用\n- 熟悉 Batch 服务的使用,包括计算环境、任务队列、任务定义的配置\n- 熟悉生信软件(bwa,samtools,coverm)的安装配置\n- 熟悉容器的使用\n\n#### **整体架构**\n\n本文演示了一个基于 Amazon Batch 服务来进行任务调度的方案, Batch 是 Amazon 托管的一个批量计算服务,用户可以通过它运行任意规模的容器化工作负载,目前已经广泛应用于基因分析、药物研发等高性能计算的场景。本方案整体架构及用到的服务如下:\n\n![image.png](https://dev-media.amazoncloud.cn/ba7484f3d41d40329d52bae3678c6cc1_image.png)\n\n方案描述:\n\n- Batch 批量计算任务调度,启动大量计算节点用于计算\n- S3 存储输入和输出数据\n- EFS 映射到容器中,用于存放运行脚本\n- DynamoDB 保存输入数据的信息及处理状态,运行脚本从中读取需要处理的文件列表并更新处理状态\n- ECR 作为容器镜像仓库\n- CloudWatch 监控性能指标及查看日志\n- 开源软件 goofys,挂载 S3存储桶到容器中,简化 S3上数据读取方式,优化 S3到 EC2的数据读取性能\n- 跳板机,用于操作云上资源\n\n软件适配\n把原先在 x86架构下的工作负载迁移到 ARM 架构下,首先我们要在 ARM 架构下完成软件的适配。本次演示主要用到 bwa,samtools 和 coverm 三个软件,以下演示如何在 ARM 架构下完成对这些软件的编译并且构建容器镜像。\n\n#### **EC2**\n\n启动一台 EC2使用作为开发环境,AMI:Amazon Linux2,实例类型 t4g.medium(必须是 Graviton 机型)。若在中国区编译 coverm 碰到网络问题,可在 Global 区域启动该 EC2,做完容器镜像后直接推送回中国区的 ECR。\n\n#### **安装 Docker**\n\n```\\nsudo yum update -y\\nsudo amazon-linux-extras install docker -y\\nsudo systemctl start docker\\nsudo systemctl enable docker\\nsudo usermod -a -G docker ec2-user\\n```\n\n登录 EC2安装 docker 后,退出,再重新登录以接受新的 docker 组权限\n\n#### **AWSCLI v2**\n\n```\\ncurl \\"https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip\\" -o \\"awscliv2.zip\\"\\nunzip awscliv2.zip\\nsudo ./aws/install\\n```\n\n\n配置好中国区 AK/SK,为了后续推送容器镜像到国内 ECR\n\n#### **基础镜像**\n\n```\\ndocker pull centos\\n```\n创建一个目录用于保存后续构建容器镜像需要的文件\n\n```\\nmkdir docker\\ncd docker\\n```\n\n#### **bwa**\n\n```\\nwget https://github.com/lh3/bwa/releases/download/v0.7.17/bwa-0.7.17.tar.bz2\\nwget https://gitlab.com/arm-hpc/packages/uploads/ca862a40906a0012de90ef7b3a98e49d/sse2neon.h\\n```\n\n#### **samtools**\n\n```\\nwget https://github.com/samtools/samtools/releases/download/1.15.1/samtools-1.15.1.tar.bz2\\n```\n\n#### **coverm**\n\n起一个容器编译 coverm\n\n```\\ndocker run --name coverm -v /home/ec2-user/docker:/data -itd centos\\n```\n\n进入容器\n\n```\\ndocker exec -it coverm bash\\nsed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \\nsed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*\\nyum install git gcc cmake3 -y\\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\\nsource \$HOME/.cargo/env\\ngit clone https://github.com/wwood/CoverM\\ncd CoverM\\ncargo build --release\\n```\n\n复制可执行文件到外部存储\n\n```\\ncp target/release/coverm /data/coverm\\n```\n\n#### **goofys**\n\ngoofys 用于将 S3存储桶映射到容器中,简化 S3文件读取,将文件直接从 S3读取到 EC2内存,无需落盘,从而加快文件读取速率\n\n编译\n\n```\\nyum install go\\ngit clone https://github.com/kahing/goofys.git\\ncd goofys\\nGOOS=linux GOARCH=arm64 go build\\n```\n\n复制可执行文件到外部存储\n\n```\\ncp goofys /data/goofys\\n```\n\n退出容器\n\n```\\nexit\\n```\n\n#### **镜像构建**\n\n确保 bwa-0.7.17.tar.bz2, samtools-1.15.1.tar.bz2, coverm, goofys, awscliv2.zip 和 sse2neon.h 已经保存到之前创建的 docker 目录,编辑如下 Dockerfile:\n\n```\\nFROM centos\\nADD bwa-0.7.17.tar.bz2 samtools-1.15.1.tar.bz2 coverm goofys awscliv2.zip sse2neon.h /opt/\\n\\nWORKDIR /opt\\nRUN \\\\ \\nsed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* && \\\\\\nsed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* && \\\\\\nyum install unzip gcc-c++ make autoconf ncurses-devel bzip2 bzip2-devel xz-devel zlib-devel fuse fuse-devel -y && \\\\\\nyum clean all && \\\\\\n#awscli\\nunzip awscliv2.zip && \\\\\\n./aws/install && \\\\\\nrm -rf awscliv2.zip aws && \\\\\\n#bwa\\ncd bwa-0.7.17 && \\\\\\nsed -i -e 's/<emmintrin.h>/\\"sse2neon.h\\"/' ksw.c && \\\\\\nmv /opt/sse2neon.h . && \\\\\\nmake && \\\\\\ncd .. && \\\\\\n#samtools\\ncd samtools-1.15.1 && \\\\\\nautoheader && \\\\\\nautoconf -Wno-syntax && \\\\\\n./configure && \\\\\\nmake && \\\\\\nmake install && \\\\\\ncd .. && \\\\\\n#coverm\\nmkdir tools && \\\\\\nmv coverm tools && \\\\\\n#goofys\\nmv goofys tools\\n\\nWORKDIR /data\\n\\nENV PATH=\$PATH:/opt/bwa-0.7.17:/opt/tools/\\n```\n\n构建镜像\n\n```\\ndocker build -t mapping-graviton . \\n```\n\n创建 ECR 镜像仓库 mapping-graviton 并查看推送命令推送镜像到该仓库\n\n![image.png](https://dev-media.amazoncloud.cn/87524bbd4b264535ab0fc9b78aeb98ec_image.png)\n\n#### **云上环境设置**\n\n**S3**\n\nS3存储桶包含3个目录\n\n![image.png](https://dev-media.amazoncloud.cn/3d822b50dc2f4817a460d987cbe180d3_image.png)\n\nsource 目录存放输入序列,results 存放结果数据\n\n![image.png](https://dev-media.amazoncloud.cn/aff9fb38508a421ab49ef675de25e78f_image.png)\n\nref_data 目录存放参考基因组的索引库\n\n![image.png](https://dev-media.amazoncloud.cn/3d954d00cbd44833be75f6162c445d51_image.png)\n\n**DynamoDB**\n\n创建一张表用于保存 S3上的输入序列信息,投递任务的脚本从表中读取需要处理的基因序列列表,循环投递任务。在任务运行的时候,根据不同的处理阶段,更新表中对应序列的状态值。\n\n参照以下命令向表中插入数据:\n\n```\\naws ddb put reads_graviton '{sample: 'SRR11676645', r1: 'source/SRR11676645_1.fastq.gz', r2: 'source/SRR11676645_2.fastq.gz', status: '0'}'\\n\\n```\n\n![image.png](https://dev-media.amazoncloud.cn/769ffb8216c24308940771d644e7a47a_image.png)\n\n#### **EFS**\n\n创建一个 EFS 文件系统(fs-0a8685ad57ce63a3f),开发环境挂载 EFS 文件系统,在文件系统中创建 mapping 目录,保存 mapping.sh 到该目录下(放在容器外面主要是为了调试及修改方便,不用每次都重新构建镜像)\n\n![image.png](https://dev-media.amazoncloud.cn/be10a13e302f4f41b5fd8bcdf14e4120_image.png)\n\n#### **EC2启动模板**\n\n修改根卷为 gp3,200G(根据实际需要调整大小),设备名称指定自定义值/dev/xvda\n\n![image.png](https://dev-media.amazoncloud.cn/50c1790f31e6441dac9699f1757a97e1_image.png)\n\n在测试阶段,若需要监控内存使用率,可在高级详细信息→用户数据,输入以下 CloudWatch Agent 配置\n\n在生产阶段,如果有大量任务运行,建议不要配置 CloudWatch Agent,因为有可能产生指标数量过多的费用\n\n```\\nMIME-Version: 1.0\\nContent-Type: multipart/mixed; boundary=\\"==MYBOUNDARY==\\"\\n\\n--==MYBOUNDARY==\\nContent-Type: text/x-shellscript; charset=\\"us-ascii\\"\\n\\n#!/bin/bash\\nyum install amazon-cloudwatch-agent -y\\ncat << EOF > /opt/aws/amazon-cloudwatch-agent/bin/config.json \\n{\\n \\"agent\\": {\\n \\"metrics_collection_interval\\": 30,\\n \\"run_as_user\\": \\"root\\"\\n },\\n \\"metrics\\": {\\n \\"append_dimensions\\": {\\n \\"InstanceId\\": \\"\\\\\${aws:InstanceId}\\",\\n \\"InstanceType\\": \\"\\\\\${aws:InstanceType}\\"\\n },\\n \\"metrics_collected\\": {\\n \\"mem\\": {\\n \\"measurement\\": [\\n \\"mem_used_percent\\"\\n ],\\n \\"metrics_collection_interval\\": 30\\n },\\n \\"swap\\": {\\n \\"measurement\\": [\\n \\"swap_used_percent\\"\\n ],\\n \\"metrics_collection_interval\\": 30\\n }\\n }\\n }\\n}\\nEOF\\n/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\\n\\n--==MYBOUNDARY==--\\n```\n\n#### **IAM 角色**\n\nBatch 需要的两个角色,附加合适的权限\n\n![image.png](https://dev-media.amazoncloud.cn/7dbf31c60b24415d923af14b3c7ddc06_image.png)\n\necsInstanceRoleBatchJobRole\n\n![image.png](https://dev-media.amazoncloud.cn/590694932fd645aebde82623d6f27e16_image.png)\n\n#### **计算环境**\n\n创建配置文件 ce.json:\n\nsubnets:配置了 NAT 网关路由的私有子网\n\nsecurityGroupIds:默认安全组 id\n\ninstanceTypes:使用的 r6g 实例类型\ntags:EC2标签\n\n123456789012:换成您自己的12位 Amazon 账户 id\n\n```\\n{\\n \\"computeEnvironmentName\\": \\"env-mapping-graviton\\",\\n \\"type\\": \\"MANAGED\\",\\n \\"state\\": \\"ENABLED\\",\\n \\"computeResources\\": {\\n \\"type\\": \\"EC2\\",\\n \\"allocationStrategy\\": \\"BEST_FIT\\",\\n \\"minvCpus\\": 0,\\n \\"maxvCpus\\": 2560,\\n \\"desiredvCpus\\": 0,\\n \\"instanceTypes\\": [\\n \\"r6g\\"\\n ],\\n \\"subnets\\": [\\n \\"subnet-03388bca5b37db2b9\\",\\n \\"subnet-0fafc120e429ec25d\\"\\n ],\\n \\"securityGroupIds\\": [\\n \\"sg-0468dd9696811b7b8\\"\\n ],\\n \\"instanceRole\\": \\"arn:aws-cn:iam::123456789012:instance-profile/ecsInstanceRole\\",\\n \\"tags\\": {\\n \\"Name\\": \\"batch-mapping-graviton\\"\\n },\\n \\"launchTemplate\\": {\\n \\"launchTemplateName\\": \\"lt-batch-zju\\",\\n \\"version\\": \\"9\\"\\n }\\n },\\n \\"serviceRole\\": \\"arn:aws-cn:iam::123456789012:role/aws-service-role/batch.amazonaws.com/AWSServiceRoleForBatch\\"\\n}\\n```\n\n创建计算环境\n\n```\\naws batch create-compute-environment --cli-input-json file://ce.json\\n```\n\n#### **任务队列**\n\n创建配置文件 jq.json:\n\ncomputeEnvironment:上一步创建的计算环境的 arn\n\n```\\n{\\n \\"jobQueueName\\": \\"q-mapping-graviton\\",\\n \\"state\\": \\"ENABLED\\",\\n \\"priority\\": 1,\\n \\"computeEnvironmentOrder\\": [\\n {\\n \\"order\\": 1,\\n \\"computeEnvironment\\": \\"arn:aws-cn:batch:cn-northwest-1:123456789012:compute-environment/env-mapping-graviton\\"\\n }\\n ]\\n}\\n```\n\n创建任务队列\n\n```\\naws batch create-job-queue --cli-input-json file://jq.json\\n\\n```\n\n#### **任务定义**\n\n创建配置文件 jd.json:\n\nprivileged: 容器中运行 goofys 需要开启特权模式,设为 true\n\n```\\n{\\n \\"jobDefinitionName\\": \\"jd-mapping-graviton\\",\\n \\"type\\": \\"container\\",\\n \\"parameters\\": {\\n \\"r2\\": \\"source/SRR11676645_2.fastq.gz\\",\\n \\"dbtable\\": \\"reads_graviton\\",\\n \\"sample\\": \\"SRR11676645\\",\\n \\"script\\": \\"mapping.sh\\",\\n \\"r1\\": \\"source/SRR11676645_1.fastq.gz\\"\\n },\\n \\"containerProperties\\": {\\n \\"image\\": \\"123456789012.dkr.ecr.cn-northwest-1.amazonaws.com.cn/mapping-graviton:latest\\",\\n \\"command\\": [\\n \\"sh\\",\\n \\"Ref::script\\",\\n \\"Ref::sample\\",\\n \\"Ref::r1\\",\\n \\"Ref::r2\\",\\n \\"Ref::dbtable\\"\\n ],\\n \\"jobRoleArn\\": \\"arn:aws-cn:iam::123456789012:role/BatchJobRole\\",\\n \\"volumes\\": [\\n {\\n \\"name\\": \\"efs\\",\\n \\"efsVolumeConfiguration\\": {\\n \\"fileSystemId\\": \\"fs-0a8685ad57ce63a3f\\",\\n \\"rootDirectory\\": \\"mapping\\"\\n }\\n }\\n ],\\n \\"environment\\": [\\n {\\n \\"name\\": \\"S3_MOUNT_POINT\\",\\n \\"value\\": \\"/s3\\"\\n }\\n ],\\n \\"mountPoints\\": [\\n {\\n \\"containerPath\\": \\"/data\\",\\n \\"sourceVolume\\": \\"efs\\"\\n }\\n ],\\n \\"privileged\\": true,\\n \\"resourceRequirements\\": [\\n {\\n \\"value\\": \\"64\\",\\n \\"type\\": \\"VCPU\\"\\n },\\n {\\n \\"value\\": \\"500000\\",\\n \\"type\\": \\"MEMORY\\"\\n }\\n ]\\n },\\n \\"platformCapabilities\\": [\\n \\"EC2\\"\\n ]\\n}\\n```\n\n注册任务定义\n\n```\\naws batch register-job-definition --cli-input-json file://jd.json\\n```\n\n#### **任务脚本 mapping.sh**\n\n实际任务运行所调用的脚本(保存到 EFS 的 mapping 目录下)\n\n```\\nsample=\$1\\nr1=\$2\\nr2=\$3\\ndbtable=\$4\\necho 'sample: '\$sample', r1: '\$r1', r2: '\$r2', dbtable: '\$dbtable\\n\\necho 'mount s3 bucket'\\nmkdir -p \$S3_MOUNT_POINT\\ngoofys --region cn-northwest-1 sun-test \$S3_MOUNT_POINT\\nbase_dir=\$S3_MOUNT_POINT\\nls -lh \$base_dir\\n\\necho 'job done set status to 1'\\naws dynamodb execute-statement --statement \\"UPDATE \$dbtable SET status=1 WHERE sample='\$sample'\\"\\n\\necho 'bwa start'\\nmkdir /result\\nbwa mem -t 64 \$base_dir/ref_data/derep_all.fa \$base_dir/\$r1 \$base_dir/\$r2 > /result/\$sample.sam\\necho 'samtools start'\\nsamtools sort /result/\$sample.sam -@ 64 -o /result/\$sample.bam\\necho 'rm sample'\\nrm /result/\$sample.sam\\n\\necho 'job done set status to 2'\\naws dynamodb execute-statement --statement \\"UPDATE \$dbtable SET status=2 WHERE sample='\$sample'\\"\\n\\necho 'coverm filter start'\\ncoverm filter --min-read-percent-identity 0.95 --min-read-aligned-percent 0.75 -b /result/\$sample.bam -o /result/\${sample}_filter.bam -t 64\\necho 'copy '\${sample}_filter.bam' to s3'\\nmkdir -p \$base_dir/results/\$dbtable\\ncp /result/\${sample}_filter.bam \$base_dir/results/\$dbtable/\\n\\necho 'job done set status to 3'\\naws dynamodb execute-statement --statement \\"UPDATE \$dbtable SET status=3 WHERE sample='\$sample'\\"\\n\\necho 'rm result '\$sample.bam' from local disk'\\nrm /result/\$sample.bam\\n\\necho 'coverm contig start'\\ncoverm contig --trim-max 90 --trim-min 10 --min-read-aligned-percent 70 -t 64 --bam-files /result/\${sample}_filter.bam > /result/\${sample}_coverage.csv\\necho 'copy to s3'\\ncp /result/\${sample}_coverage.csv \$base_dir/results/\$dbtable\\n\\necho 'job done set status to 4'\\naws dynamodb execute-statement --statement \\"UPDATE \$dbtable SET status=4 WHERE sample='\$sample'\\"\\n\\necho 'rm result '\${sample}_filter.bam' from local disk'\\nrm /result/\${sample}_filter.bam\\n```\n\n#### **run_mapping.sh**\n\n通过 run_mapping.sh 来读取数据库中序列信息并循环提交多个 Batch 任务,该脚本可在跳板机或本地执行\n\n```\\ndbtable='reads_graviton'\\nitem=`aws ddb select \$dbtable --filter 'status = 0' `\\ncount=`echo \$item | awk '{print \$2}'`\\necho 'count: '\$count\\nif [ \$count -eq 0 ]\\nthen\\n echo 'end'\\n break\\nfi\\ninfo=`echo \$item | awk '{for(i=10;i<=NF;i=i+9){print \$i}}'`\\nfastq_1=`echo \$item | awk '{for(i=6;i<=NF;i=i+9){print \$i}}'`\\nfastq_2=`echo \$item | awk '{for(i=8;i<=NF;i=i+9){print \$i}}'`\\n\\nfor ((i=1;i<=\$count;i++))\\ndo\\n sample=`echo \$info|awk '{print \$'\$i'}'`\\n echo 'sample= '\$sample\\n r1=`echo \$fastq_1|awk '{print \$'\$i'}'`\\n echo 'r1= '\$r1\\n r2=`echo \$fastq_2|awk '{print \$'\$i'}'`\\n echo 'r2= '\$r2 \\n jobname=\${dbtable}_\${sample%.*}\\n echo 'jobnane= '\$jobname\\n aws batch submit-job --job-name \$jobname --job-queue q-mapping-graviton --job-definition jd-mapping-graviton:1 --parameters script=mapping.sh,sample=\$sample,r1=\$r1,r2=\$r2,dbtable=\$dbtable\\ndone\\n```\n\n#### **测试**\n\n按照类似的方法再创建一套基于 x86架构的 Batch 计算环境、任务队列、任务定义(不再赘述创建方法),相同的任务分别投递到 arm 和 x86环境,进行对比测试。\n\n单个序列比对任务需要用到的内存为300G+,故使用类型为r6g.16xlarge 和 r5.16xlarge 的 EC2实例进行对比测试, 测试结果如下:\n\n#### **CPU/MEM 监控-CloudWatch**\n\nSRR11676645\n\n![image.png](https://dev-media.amazoncloud.cn/efe04b4a5b184086a25ddeb0da4da158_image.png)\n\nSRR11676933\n\n![image.png](https://dev-media.amazoncloud.cn/c166192a10dd4991a4c88dc51a7921e5_image.png)\n\nFDMS190655335\n\n![image.png](https://dev-media.amazoncloud.cn/0d28ea7e9b5945cb839e99b99bad130c_image.png)\n\n在计算阶段,r6g.16xlarge 和 r5.16xlarge 的资源利用率几乎一致,CPU 利用率都能到100%,内存利用率都为60%左右\n\n#### **用时**\n\n![image.png](https://dev-media.amazoncloud.cn/448901c6ef8747a8bc99bbf4c80326db_image.png)\n\nr6g.16xlarge 相对 r5.16xlarge 所需时间大约减少16%左右\n\n#### **EC2价格对比**\n\n![image.png](https://dev-media.amazoncloud.cn/a8028775708c4dbf9c01cc9d744faed4_image.png)\n\nr6g.16xlarge相对r5.16xlargeEC2价格大约下降20%左右\n\n#### **结论**\n\n基于 Batch 的任务调度,在计算任务完成之后,Batch 会自动终止不再运行任务的 EC2实例,所以时间的节约也能带来 EC2和 EBS 的成本节约。根据以上测试结果,在基因测序序列比对这个场景下,使用 ARM 架构的 Graviton 实例,相对于5代 x86实例,能有:\n\n- 16%左右时间节约\n- 16%左右 EBS 成本节约\n- 1 – (1-16%) x (1-20%) = 32.8%左右 EC2成本节约\n\n在这篇文章中,我们演示了如何基于 Graviton2处理器所支持的 EC2实例,在 Amazon 上使用 Batch 服务来运行基因测序的工作负载。并且根据测试的结果,使用 Graviton2处理器用于基因测序的序列比对场景,能够很好的满足用户对于性能和成本的需求。只要您的工作负载所用的操作系统和软件能够适配 ARM 架构,在 Amazon 上就可以利用 Graviton 处理器高性价比的特点来达到降本增效的目的。\n\n#### **参考文档**\n\nAmazon Batch 用户指南:\n\n[https://docs.aws.amazon.com/zh_cn/batch/latest/userguide/what-is-batch.html](https://docs.aws.amazon.com/zh_cn/batch/latest/userguide/what-is-batch.html)\n\n利用 Amazon Batch 来为容器化负载调用海量云端算力:\n\n[https://aws.amazon.com/cn/blogs/china/use-aws-batch-to-call-massive-cloud-computing-power-for-containerized-loads/](https://aws.amazon.com/cn/blogs/china/use-aws-batch-to-call-massive-cloud-computing-power-for-containerized-loads/)\n\n在云中对基因组学工作负载进行基准测试的通用方法:在 Graviton2 上运行 BWA 读取对齐器:\n\n[https://aws.amazon.com/cn/blogs/publicsector/generalized-approach-benchmarking-genomics-workloads-cloud-bwa-read-aligner-graviton2/](https://aws.amazon.com/cn/blogs/publicsector/generalized-approach-benchmarking-genomics-workloads-cloud-bwa-read-aligner-graviton2/)\n\n#### **本篇作者**\n\n![image.png](https://dev-media.amazoncloud.cn/cd5861c11fc24d2ea501d3bee6f7fbc8_image.png)\n\n#### **孙亮**\n\nAmazon 解决方案架构师,硕士毕业于浙江大学计算机系。在加入 Amazon 之前,拥有多年软件行业开发经验。目前在 Public Sector 部门主要服务于生命科学和医疗健康相关的行业客户,致力于提供有关 HPC、容器、[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)、数据安全等各类云计算解决方案的咨询与架构设计。\n\n![image.png](https://dev-media.amazoncloud.cn/ead06b58fad945b098a63427f6b46e7b_image.png)\n\n#### **刘光**\n\nAmazon 资深解决方案架构师,目前负责基于 Amazon 云计算方案架构的咨询和设计,同时致力于 Amazon 云服务在政企、教育和医疗行业客户的推广。在加入 Amazon 之前就职于 Citrix,具有多年企业虚拟化、VDI 架构设计和支持经验。\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","render":"<h4><a id=\\"_0\\"></a><strong>概述</strong></h4>\\n<p>相对于基于传统 x86架构的处理器来说,Amazon 设计的基于 ARM 架构的 Graviton 处理器为 EC2中运行的云工作负载提供了更佳的性价比。基于 Graviton2 的实例支持广泛的通用型、突发型、计算优化型、内存优化型、存储优化型和加速计算型工作负载,包括应用程序服务器、微服务、高性能计算 (HPC)、基于 CPU 的机器学习 (ML) 推理、视频编码、电子设计自动化、游戏、开源数据库和内存中的缓存等。由 Graviton2 处理器支持的 EC2实例 (M6g、C6g、R6g和T4g) 在中国区已经上线一段时间,本文以土壤微生物宏基因测序为例,来演示如何利用Amazon Batch 服务调用基于 Graviton2处理器的实例用于基因分析,并且验证 Graviton2相对于 x86架构的处理器能够给用户带来的收益。</p>\n<h4><a id=\\"_4\\"></a><strong>先决条件</strong></h4>\\n<p>您需要一个 Amazon 帐户来完成本演练,其它条件包括(本篇不再描述其具体使用方式):</p>\n<ul>\\n<li><a href=\\"https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/install-cliv2-linux.html\\" target=\\"_blank\\">Amazon CLI v2</a>安装和配置</li>\\n<li>完成 VPC 的设置,包括公有子网、私有子网和 NAT 的配置等</li>\n<li>熟悉 EC2服务的使用,熟悉 EFS、S3等存储服务的使用</li>\n<li>熟悉 Batch 服务的使用,包括计算环境、任务队列、任务定义的配置</li>\n<li>熟悉生信软件(bwa,samtools,coverm)的安装配置</li>\n<li>熟悉容器的使用</li>\n</ul>\\n<h4><a id=\\"_15\\"></a><strong>整体架构</strong></h4>\\n<p>本文演示了一个基于 Amazon Batch 服务来进行任务调度的方案, Batch 是 Amazon 托管的一个批量计算服务,用户可以通过它运行任意规模的容器化工作负载,目前已经广泛应用于基因分析、药物研发等高性能计算的场景。本方案整体架构及用到的服务如下:</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/ba7484f3d41d40329d52bae3678c6cc1_image.png\\" alt=\\"image.png\\" /></p>\n<p>方案描述:</p>\n<ul>\\n<li>Batch 批量计算任务调度,启动大量计算节点用于计算</li>\n<li>S3 存储输入和输出数据</li>\n<li>EFS 映射到容器中,用于存放运行脚本</li>\n<li>DynamoDB 保存输入数据的信息及处理状态,运行脚本从中读取需要处理的文件列表并更新处理状态</li>\n<li>ECR 作为容器镜像仓库</li>\n<li>CloudWatch 监控性能指标及查看日志</li>\n<li>开源软件 goofys,挂载 S3存储桶到容器中,简化 S3上数据读取方式,优化 S3到 EC2的数据读取性能</li>\n<li>跳板机,用于操作云上资源</li>\n</ul>\\n<p>软件适配<br />\\n把原先在 x86架构下的工作负载迁移到 ARM 架构下,首先我们要在 ARM 架构下完成软件的适配。本次演示主要用到 bwa,samtools 和 coverm 三个软件,以下演示如何在 ARM 架构下完成对这些软件的编译并且构建容器镜像。</p>\n<h4><a id=\\"EC2_35\\"></a><strong>EC2</strong></h4>\\n<p>启动一台 EC2使用作为开发环境,AMI:Amazon Linux2,实例类型 t4g.medium(必须是 Graviton 机型)。若在中国区编译 coverm 碰到网络问题,可在 Global 区域启动该 EC2,做完容器镜像后直接推送回中国区的 ECR。</p>\n<h4><a id=\\"_Docker_39\\"></a><strong>安装 Docker</strong></h4>\\n<pre><code class=\\"lang-\\">sudo yum update -y\\nsudo amazon-linux-extras install docker -y\\nsudo systemctl start docker\\nsudo systemctl enable docker\\nsudo usermod -a -G docker ec2-user\\n</code></pre>\\n<p>登录 EC2安装 docker 后,退出,再重新登录以接受新的 docker 组权限</p>\n<h4><a id=\\"AWSCLI_v2_51\\"></a><strong>AWSCLI v2</strong></h4>\\n<pre><code class=\\"lang-\\">curl &quot;https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip&quot; -o &quot;awscliv2.zip&quot;\\nunzip awscliv2.zip\\nsudo ./aws/install\\n</code></pre>\\n<p>配置好中国区 AK/SK,为了后续推送容器镜像到国内 ECR</p>\n<h4><a id=\\"_62\\"></a><strong>基础镜像</strong></h4>\\n<pre><code class=\\"lang-\\">docker pull centos\\n</code></pre>\\n<p>创建一个目录用于保存后续构建容器镜像需要的文件</p>\n<pre><code class=\\"lang-\\">mkdir docker\\ncd docker\\n</code></pre>\\n<h4><a id=\\"bwa_74\\"></a><strong>bwa</strong></h4>\\n<pre><code class=\\"lang-\\">wget https://github.com/lh3/bwa/releases/download/v0.7.17/bwa-0.7.17.tar.bz2\\nwget https://gitlab.com/arm-hpc/packages/uploads/ca862a40906a0012de90ef7b3a98e49d/sse2neon.h\\n</code></pre>\\n<h4><a id=\\"samtools_81\\"></a><strong>samtools</strong></h4>\\n<pre><code class=\\"lang-\\">wget https://github.com/samtools/samtools/releases/download/1.15.1/samtools-1.15.1.tar.bz2\\n</code></pre>\\n<h4><a id=\\"coverm_87\\"></a><strong>coverm</strong></h4>\\n<p>起一个容器编译 coverm</p>\n<pre><code class=\\"lang-\\">docker run --name coverm -v /home/ec2-user/docker:/data -itd centos\\n</code></pre>\\n<p>进入容器</p>\n<pre><code class=\\"lang-\\">docker exec -it coverm bash\\nsed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* \\nsed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*\\nyum install git gcc cmake3 -y\\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\\nsource \$HOME/.cargo/env\\ngit clone https://github.com/wwood/CoverM\\ncd CoverM\\ncargo build --release\\n</code></pre>\\n<p>复制可执行文件到外部存储</p>\n<pre><code class=\\"lang-\\">cp target/release/coverm /data/coverm\\n</code></pre>\\n<h4><a id=\\"goofys_115\\"></a><strong>goofys</strong></h4>\\n<p>goofys 用于将 S3存储桶映射到容器中,简化 S3文件读取,将文件直接从 S3读取到 EC2内存,无需落盘,从而加快文件读取速率</p>\n<p>编译</p>\n<pre><code class=\\"lang-\\">yum install go\\ngit clone https://github.com/kahing/goofys.git\\ncd goofys\\nGOOS=linux GOARCH=arm64 go build\\n</code></pre>\\n<p>复制可执行文件到外部存储</p>\n<pre><code class=\\"lang-\\">cp goofys /data/goofys\\n</code></pre>\\n<p>退出容器</p>\n<pre><code class=\\"lang-\\">exit\\n</code></pre>\\n<h4><a id=\\"_140\\"></a><strong>镜像构建</strong></h4>\\n<p>确保 bwa-0.7.17.tar.bz2, samtools-1.15.1.tar.bz2, coverm, goofys, awscliv2.zip 和 sse2neon.h 已经保存到之前创建的 docker 目录,编辑如下 Dockerfile:</p>\n<pre><code class=\\"lang-\\">FROM centos\\nADD bwa-0.7.17.tar.bz2 samtools-1.15.1.tar.bz2 coverm goofys awscliv2.zip sse2neon.h /opt/\\n\\nWORKDIR /opt\\nRUN \\\\ \\nsed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* &amp;&amp; \\\\\\nsed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* &amp;&amp; \\\\\\nyum install unzip gcc-c++ make autoconf ncurses-devel bzip2 bzip2-devel xz-devel zlib-devel fuse fuse-devel -y &amp;&amp; \\\\\\nyum clean all &amp;&amp; \\\\\\n#awscli\\nunzip awscliv2.zip &amp;&amp; \\\\\\n./aws/install &amp;&amp; \\\\\\nrm -rf awscliv2.zip aws &amp;&amp; \\\\\\n#bwa\\ncd bwa-0.7.17 &amp;&amp; \\\\\\nsed -i -e 's/&lt;emmintrin.h&gt;/&quot;sse2neon.h&quot;/' ksw.c &amp;&amp; \\\\\\nmv /opt/sse2neon.h . &amp;&amp; \\\\\\nmake &amp;&amp; \\\\\\ncd .. &amp;&amp; \\\\\\n#samtools\\ncd samtools-1.15.1 &amp;&amp; \\\\\\nautoheader &amp;&amp; \\\\\\nautoconf -Wno-syntax &amp;&amp; \\\\\\n./configure &amp;&amp; \\\\\\nmake &amp;&amp; \\\\\\nmake install &amp;&amp; \\\\\\ncd .. &amp;&amp; \\\\\\n#coverm\\nmkdir tools &amp;&amp; \\\\\\nmv coverm tools &amp;&amp; \\\\\\n#goofys\\nmv goofys tools\\n\\nWORKDIR /data\\n\\nENV PATH=\$PATH:/opt/bwa-0.7.17:/opt/tools/\\n</code></pre>\\n<p>构建镜像</p>\n<pre><code class=\\"lang-\\">docker build -t mapping-graviton . \\n</code></pre>\\n<p>创建 ECR 镜像仓库 mapping-graviton 并查看推送命令推送镜像到该仓库</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/87524bbd4b264535ab0fc9b78aeb98ec_image.png\\" alt=\\"image.png\\" /></p>\n<h4><a id=\\"_193\\"></a><strong>云上环境设置</strong></h4>\\n<p><strong>S3</strong></p>\\n<p>S3存储桶包含3个目录</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/3d822b50dc2f4817a460d987cbe180d3_image.png\\" alt=\\"image.png\\" /></p>\n<p>source 目录存放输入序列,results 存放结果数据</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/aff9fb38508a421ab49ef675de25e78f_image.png\\" alt=\\"image.png\\" /></p>\n<p>ref_data 目录存放参考基因组的索引库</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/3d954d00cbd44833be75f6162c445d51_image.png\\" alt=\\"image.png\\" /></p>\n<p><strong>DynamoDB</strong></p>\\n<p>创建一张表用于保存 S3上的输入序列信息,投递任务的脚本从表中读取需要处理的基因序列列表,循环投递任务。在任务运行的时候,根据不同的处理阶段,更新表中对应序列的状态值。</p>\n<p>参照以下命令向表中插入数据:</p>\n<pre><code class=\\"lang-\\">aws ddb put reads_graviton '{sample: 'SRR11676645', r1: 'source/SRR11676645_1.fastq.gz', r2: 'source/SRR11676645_2.fastq.gz', status: '0'}'\\n\\n</code></pre>\\n<p><img src=\\"https://dev-media.amazoncloud.cn/769ffb8216c24308940771d644e7a47a_image.png\\" alt=\\"image.png\\" /></p>\n<h4><a id=\\"EFS_222\\"></a><strong>EFS</strong></h4>\\n<p>创建一个 EFS 文件系统(fs-0a8685ad57ce63a3f),开发环境挂载 EFS 文件系统,在文件系统中创建 mapping 目录,保存 mapping.sh 到该目录下(放在容器外面主要是为了调试及修改方便,不用每次都重新构建镜像)</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/be10a13e302f4f41b5fd8bcdf14e4120_image.png\\" alt=\\"image.png\\" /></p>\n<h4><a id=\\"EC2_228\\"></a><strong>EC2启动模板</strong></h4>\\n<p>修改根卷为 gp3,200G(根据实际需要调整大小),设备名称指定自定义值/dev/xvda</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/50c1790f31e6441dac9699f1757a97e1_image.png\\" alt=\\"image.png\\" /></p>\n<p>在测试阶段,若需要监控内存使用率,可在高级详细信息→用户数据,输入以下 CloudWatch Agent 配置</p>\n<p>在生产阶段,如果有大量任务运行,建议不要配置 CloudWatch Agent,因为有可能产生指标数量过多的费用</p>\n<pre><code class=\\"lang-\\">MIME-Version: 1.0\\nContent-Type: multipart/mixed; boundary=&quot;==MYBOUNDARY==&quot;\\n\\n--==MYBOUNDARY==\\nContent-Type: text/x-shellscript; charset=&quot;us-ascii&quot;\\n\\n#!/bin/bash\\nyum install amazon-cloudwatch-agent -y\\ncat &lt;&lt; EOF &gt; /opt/aws/amazon-cloudwatch-agent/bin/config.json \\n{\\n &quot;agent&quot;: {\\n &quot;metrics_collection_interval&quot;: 30,\\n &quot;run_as_user&quot;: &quot;root&quot;\\n },\\n &quot;metrics&quot;: {\\n &quot;append_dimensions&quot;: {\\n &quot;InstanceId&quot;: &quot;\\\\\${aws:InstanceId}&quot;,\\n &quot;InstanceType&quot;: &quot;\\\\\${aws:InstanceType}&quot;\\n },\\n &quot;metrics_collected&quot;: {\\n &quot;mem&quot;: {\\n &quot;measurement&quot;: [\\n &quot;mem_used_percent&quot;\\n ],\\n &quot;metrics_collection_interval&quot;: 30\\n },\\n &quot;swap&quot;: {\\n &quot;measurement&quot;: [\\n &quot;swap_used_percent&quot;\\n ],\\n &quot;metrics_collection_interval&quot;: 30\\n }\\n }\\n }\\n}\\nEOF\\n/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\\n\\n--==MYBOUNDARY==--\\n</code></pre>\\n<h4><a id=\\"IAM__280\\"></a><strong>IAM 角色</strong></h4>\\n<p>Batch 需要的两个角色,附加合适的权限</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/7dbf31c60b24415d923af14b3c7ddc06_image.png\\" alt=\\"image.png\\" /></p>\n<p>ecsInstanceRoleBatchJobRole</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/590694932fd645aebde82623d6f27e16_image.png\\" alt=\\"image.png\\" /></p>\n<h4><a id=\\"_290\\"></a><strong>计算环境</strong></h4>\\n<p>创建配置文件 ce.json:</p>\n<p>subnets:配置了 NAT 网关路由的私有子网</p>\n<p>securityGroupIds:默认安全组 id</p>\n<p>instanceTypes:使用的 r6g 实例类型<br />\\ntags:EC2标签</p>\n<p>123456789012:换成您自己的12位 Amazon 账户 id</p>\n<pre><code class=\\"lang-\\">{\\n &quot;computeEnvironmentName&quot;: &quot;env-mapping-graviton&quot;,\\n &quot;type&quot;: &quot;MANAGED&quot;,\\n &quot;state&quot;: &quot;ENABLED&quot;,\\n &quot;computeResources&quot;: {\\n &quot;type&quot;: &quot;EC2&quot;,\\n &quot;allocationStrategy&quot;: &quot;BEST_FIT&quot;,\\n &quot;minvCpus&quot;: 0,\\n &quot;maxvCpus&quot;: 2560,\\n &quot;desiredvCpus&quot;: 0,\\n &quot;instanceTypes&quot;: [\\n &quot;r6g&quot;\\n ],\\n &quot;subnets&quot;: [\\n &quot;subnet-03388bca5b37db2b9&quot;,\\n &quot;subnet-0fafc120e429ec25d&quot;\\n ],\\n &quot;securityGroupIds&quot;: [\\n &quot;sg-0468dd9696811b7b8&quot;\\n ],\\n &quot;instanceRole&quot;: &quot;arn:aws-cn:iam::123456789012:instance-profile/ecsInstanceRole&quot;,\\n &quot;tags&quot;: {\\n &quot;Name&quot;: &quot;batch-mapping-graviton&quot;\\n },\\n &quot;launchTemplate&quot;: {\\n &quot;launchTemplateName&quot;: &quot;lt-batch-zju&quot;,\\n &quot;version&quot;: &quot;9&quot;\\n }\\n },\\n &quot;serviceRole&quot;: &quot;arn:aws-cn:iam::123456789012:role/aws-service-role/batch.amazonaws.com/AWSServiceRoleForBatch&quot;\\n}\\n</code></pre>\\n<p>创建计算环境</p>\n<pre><code class=\\"lang-\\">aws batch create-compute-environment --cli-input-json file://ce.json\\n</code></pre>\\n<h4><a id=\\"_343\\"></a><strong>任务队列</strong></h4>\\n<p>创建配置文件 jq.json:</p>\n<p>computeEnvironment:上一步创建的计算环境的 arn</p>\n<pre><code class=\\"lang-\\">{\\n &quot;jobQueueName&quot;: &quot;q-mapping-graviton&quot;,\\n &quot;state&quot;: &quot;ENABLED&quot;,\\n &quot;priority&quot;: 1,\\n &quot;computeEnvironmentOrder&quot;: [\\n {\\n &quot;order&quot;: 1,\\n &quot;computeEnvironment&quot;: &quot;arn:aws-cn:batch:cn-northwest-1:123456789012:compute-environment/env-mapping-graviton&quot;\\n }\\n ]\\n}\\n</code></pre>\\n<p>创建任务队列</p>\n<pre><code class=\\"lang-\\">aws batch create-job-queue --cli-input-json file://jq.json\\n\\n</code></pre>\\n<h4><a id=\\"_370\\"></a><strong>任务定义</strong></h4>\\n<p>创建配置文件 jd.json:</p>\n<p>privileged: 容器中运行 goofys 需要开启特权模式,设为 true</p>\n<pre><code class=\\"lang-\\">{\\n &quot;jobDefinitionName&quot;: &quot;jd-mapping-graviton&quot;,\\n &quot;type&quot;: &quot;container&quot;,\\n &quot;parameters&quot;: {\\n &quot;r2&quot;: &quot;source/SRR11676645_2.fastq.gz&quot;,\\n &quot;dbtable&quot;: &quot;reads_graviton&quot;,\\n &quot;sample&quot;: &quot;SRR11676645&quot;,\\n &quot;script&quot;: &quot;mapping.sh&quot;,\\n &quot;r1&quot;: &quot;source/SRR11676645_1.fastq.gz&quot;\\n },\\n &quot;containerProperties&quot;: {\\n &quot;image&quot;: &quot;123456789012.dkr.ecr.cn-northwest-1.amazonaws.com.cn/mapping-graviton:latest&quot;,\\n &quot;command&quot;: [\\n &quot;sh&quot;,\\n &quot;Ref::script&quot;,\\n &quot;Ref::sample&quot;,\\n &quot;Ref::r1&quot;,\\n &quot;Ref::r2&quot;,\\n &quot;Ref::dbtable&quot;\\n ],\\n &quot;jobRoleArn&quot;: &quot;arn:aws-cn:iam::123456789012:role/BatchJobRole&quot;,\\n &quot;volumes&quot;: [\\n {\\n &quot;name&quot;: &quot;efs&quot;,\\n &quot;efsVolumeConfiguration&quot;: {\\n &quot;fileSystemId&quot;: &quot;fs-0a8685ad57ce63a3f&quot;,\\n &quot;rootDirectory&quot;: &quot;mapping&quot;\\n }\\n }\\n ],\\n &quot;environment&quot;: [\\n {\\n &quot;name&quot;: &quot;S3_MOUNT_POINT&quot;,\\n &quot;value&quot;: &quot;/s3&quot;\\n }\\n ],\\n &quot;mountPoints&quot;: [\\n {\\n &quot;containerPath&quot;: &quot;/data&quot;,\\n &quot;sourceVolume&quot;: &quot;efs&quot;\\n }\\n ],\\n &quot;privileged&quot;: true,\\n &quot;resourceRequirements&quot;: [\\n {\\n &quot;value&quot;: &quot;64&quot;,\\n &quot;type&quot;: &quot;VCPU&quot;\\n },\\n {\\n &quot;value&quot;: &quot;500000&quot;,\\n &quot;type&quot;: &quot;MEMORY&quot;\\n }\\n ]\\n },\\n &quot;platformCapabilities&quot;: [\\n &quot;EC2&quot;\\n ]\\n}\\n</code></pre>\\n<p>注册任务定义</p>\n<pre><code class=\\"lang-\\">aws batch register-job-definition --cli-input-json file://jd.json\\n</code></pre>\\n<h4><a id=\\"_mappingsh_443\\"></a><strong>任务脚本 mapping.sh</strong></h4>\\n<p>实际任务运行所调用的脚本(保存到 EFS 的 mapping 目录下)</p>\n<pre><code class=\\"lang-\\">sample=\$1\\nr1=\$2\\nr2=\$3\\ndbtable=\$4\\necho 'sample: '\$sample', r1: '\$r1', r2: '\$r2', dbtable: '\$dbtable\\n\\necho 'mount s3 bucket'\\nmkdir -p \$S3_MOUNT_POINT\\ngoofys --region cn-northwest-1 sun-test \$S3_MOUNT_POINT\\nbase_dir=\$S3_MOUNT_POINT\\nls -lh \$base_dir\\n\\necho 'job done set status to 1'\\naws dynamodb execute-statement --statement &quot;UPDATE \$dbtable SET status=1 WHERE sample='\$sample'&quot;\\n\\necho 'bwa start'\\nmkdir /result\\nbwa mem -t 64 \$base_dir/ref_data/derep_all.fa \$base_dir/\$r1 \$base_dir/\$r2 &gt; /result/\$sample.sam\\necho 'samtools start'\\nsamtools sort /result/\$sample.sam -@ 64 -o /result/\$sample.bam\\necho 'rm sample'\\nrm /result/\$sample.sam\\n\\necho 'job done set status to 2'\\naws dynamodb execute-statement --statement &quot;UPDATE \$dbtable SET status=2 WHERE sample='\$sample'&quot;\\n\\necho 'coverm filter start'\\ncoverm filter --min-read-percent-identity 0.95 --min-read-aligned-percent 0.75 -b /result/\$sample.bam -o /result/\${sample}_filter.bam -t 64\\necho 'copy '\${sample}_filter.bam' to s3'\\nmkdir -p \$base_dir/results/\$dbtable\\ncp /result/\${sample}_filter.bam \$base_dir/results/\$dbtable/\\n\\necho 'job done set status to 3'\\naws dynamodb execute-statement --statement &quot;UPDATE \$dbtable SET status=3 WHERE sample='\$sample'&quot;\\n\\necho 'rm result '\$sample.bam' from local disk'\\nrm /result/\$sample.bam\\n\\necho 'coverm contig start'\\ncoverm contig --trim-max 90 --trim-min 10 --min-read-aligned-percent 70 -t 64 --bam-files /result/\${sample}_filter.bam &gt; /result/\${sample}_coverage.csv\\necho 'copy to s3'\\ncp /result/\${sample}_coverage.csv \$base_dir/results/\$dbtable\\n\\necho 'job done set status to 4'\\naws dynamodb execute-statement --statement &quot;UPDATE \$dbtable SET status=4 WHERE sample='\$sample'&quot;\\n\\necho 'rm result '\${sample}_filter.bam' from local disk'\\nrm /result/\${sample}_filter.bam\\n</code></pre>\\n<h4><a id=\\"run_mappingsh_498\\"></a><strong>run_mapping.sh</strong></h4>\\n<p>通过 run_mapping.sh 来读取数据库中序列信息并循环提交多个 Batch 任务,该脚本可在跳板机或本地执行</p>\n<pre><code class=\\"lang-\\">dbtable='reads_graviton'\\nitem=`aws ddb select \$dbtable --filter 'status = 0' `\\ncount=`echo \$item | awk '{print \$2}'`\\necho 'count: '\$count\\nif [ \$count -eq 0 ]\\nthen\\n echo 'end'\\n break\\nfi\\ninfo=`echo \$item | awk '{for(i=10;i&lt;=NF;i=i+9){print \$i}}'`\\nfastq_1=`echo \$item | awk '{for(i=6;i&lt;=NF;i=i+9){print \$i}}'`\\nfastq_2=`echo \$item | awk '{for(i=8;i&lt;=NF;i=i+9){print \$i}}'`\\n\\nfor ((i=1;i&lt;=\$count;i++))\\ndo\\n sample=`echo \$info|awk '{print \$'\$i'}'`\\n echo 'sample= '\$sample\\n r1=`echo \$fastq_1|awk '{print \$'\$i'}'`\\n echo 'r1= '\$r1\\n r2=`echo \$fastq_2|awk '{print \$'\$i'}'`\\n echo 'r2= '\$r2 \\n jobname=\${dbtable}_\${sample%.*}\\n echo 'jobnane= '\$jobname\\n aws batch submit-job --job-name \$jobname --job-queue q-mapping-graviton --job-definition jd-mapping-graviton:1 --parameters script=mapping.sh,sample=\$sample,r1=\$r1,r2=\$r2,dbtable=\$dbtable\\ndone\\n</code></pre>\\n<h4><a id=\\"_530\\"></a><strong>测试</strong></h4>\\n<p>按照类似的方法再创建一套基于 x86架构的 Batch 计算环境、任务队列、任务定义(不再赘述创建方法),相同的任务分别投递到 arm 和 x86环境,进行对比测试。</p>\n<p>单个序列比对任务需要用到的内存为300G+,故使用类型为r6g.16xlarge 和 r5.16xlarge 的 EC2实例进行对比测试, 测试结果如下:</p>\n<h4><a id=\\"CPUMEM_CloudWatch_536\\"></a><strong>CPU/MEM 监控-CloudWatch</strong></h4>\\n<p>SRR11676645</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/efe04b4a5b184086a25ddeb0da4da158_image.png\\" alt=\\"image.png\\" /></p>\n<p>SRR11676933</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/c166192a10dd4991a4c88dc51a7921e5_image.png\\" alt=\\"image.png\\" /></p>\n<p>FDMS190655335</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/0d28ea7e9b5945cb839e99b99bad130c_image.png\\" alt=\\"image.png\\" /></p>\n<p>在计算阶段,r6g.16xlarge 和 r5.16xlarge 的资源利用率几乎一致,CPU 利用率都能到100%,内存利用率都为60%左右</p>\n<h4><a id=\\"_552\\"></a><strong>用时</strong></h4>\\n<p><img src=\\"https://dev-media.amazoncloud.cn/448901c6ef8747a8bc99bbf4c80326db_image.png\\" alt=\\"image.png\\" /></p>\n<p>r6g.16xlarge 相对 r5.16xlarge 所需时间大约减少16%左右</p>\n<h4><a id=\\"EC2_558\\"></a><strong>EC2价格对比</strong></h4>\\n<p><img src=\\"https://dev-media.amazoncloud.cn/a8028775708c4dbf9c01cc9d744faed4_image.png\\" alt=\\"image.png\\" /></p>\n<p>r6g.16xlarge相对r5.16xlargeEC2价格大约下降20%左右</p>\n<h4><a id=\\"_564\\"></a><strong>结论</strong></h4>\\n<p>基于 Batch 的任务调度,在计算任务完成之后,Batch 会自动终止不再运行任务的 EC2实例,所以时间的节约也能带来 EC2和 EBS 的成本节约。根据以上测试结果,在基因测序序列比对这个场景下,使用 ARM 架构的 Graviton 实例,相对于5代 x86实例,能有:</p>\n<ul>\\n<li>16%左右时间节约</li>\n<li>16%左右 EBS 成本节约</li>\n<li>1 – (1-16%) x (1-20%) = 32.8%左右 EC2成本节约</li>\n</ul>\\n<p>在这篇文章中,我们演示了如何基于 Graviton2处理器所支持的 EC2实例,在 Amazon 上使用 Batch 服务来运行基因测序的工作负载。并且根据测试的结果,使用 Graviton2处理器用于基因测序的序列比对场景,能够很好的满足用户对于性能和成本的需求。只要您的工作负载所用的操作系统和软件能够适配 ARM 架构,在 Amazon 上就可以利用 Graviton 处理器高性价比的特点来达到降本增效的目的。</p>\n<h4><a id=\\"_574\\"></a><strong>参考文档</strong></h4>\\n<p>Amazon Batch 用户指南:</p>\n<p><a href=\\"https://docs.aws.amazon.com/zh_cn/batch/latest/userguide/what-is-batch.html\\" target=\\"_blank\\">https://docs.aws.amazon.com/zh_cn/batch/latest/userguide/what-is-batch.html</a></p>\\n<p>利用 Amazon Batch 来为容器化负载调用海量云端算力:</p>\n<p><a href=\\"https://aws.amazon.com/cn/blogs/china/use-aws-batch-to-call-massive-cloud-computing-power-for-containerized-loads/\\" target=\\"_blank\\">https://aws.amazon.com/cn/blogs/china/use-aws-batch-to-call-massive-cloud-computing-power-for-containerized-loads/</a></p>\\n<p>在云中对基因组学工作负载进行基准测试的通用方法:在 Graviton2 上运行 BWA 读取对齐器:</p>\n<p><a href=\\"https://aws.amazon.com/cn/blogs/publicsector/generalized-approach-benchmarking-genomics-workloads-cloud-bwa-read-aligner-graviton2/\\" target=\\"_blank\\">https://aws.amazon.com/cn/blogs/publicsector/generalized-approach-benchmarking-genomics-workloads-cloud-bwa-read-aligner-graviton2/</a></p>\\n<h4><a id=\\"_588\\"></a><strong>本篇作者</strong></h4>\\n<p><img src=\\"https://dev-media.amazoncloud.cn/cd5861c11fc24d2ea501d3bee6f7fbc8_image.png\\" alt=\\"image.png\\" /></p>\n<h4><a id=\\"_592\\"></a><strong>孙亮</strong></h4>\\n<p>Amazon 解决方案架构师,硕士毕业于浙江大学计算机系。在加入 Amazon 之前,拥有多年软件行业开发经验。目前在 Public Sector 部门主要服务于生命科学和医疗健康相关的行业客户,致力于提供有关 HPC、容器、无服务器、数据安全等各类云计算解决方案的咨询与架构设计。</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/ead06b58fad945b098a63427f6b46e7b_image.png\\" alt=\\"image.png\\" /></p>\n<h4><a id=\\"_598\\"></a><strong>刘光</strong></h4>\\n<p>Amazon 资深解决方案架构师,目前负责基于 Amazon 云计算方案架构的咨询和设计,同时致力于 Amazon 云服务在政企、教育和医疗行业客户的推广。在加入 Amazon 之前就职于 Citrix,具有多年企业虚拟化、VDI 架构设计和支持经验。</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭