Spark SQL 任务迁移到 Amazon EMR 及性能调优

46ea55a5570795812c2de60e446242a0.gif

背景介绍

IDC 客户上云也会伴随将 IDC 中的一些大数据的工作负载迁移到云上来,和大多数线下 Hadoop 集群相比,亚马逊云科技也提供了更为适合云上的 Hadoop 服务:Amazon EMR 。本文针对 Hadoop 常见的 SQL 任务迁移上云提供了一些优化总结,帮助客户规划整体迁移方案,包含使用 Amazon EMR 时候更多考虑长时间稳定运行还是临时工作负载和确认是否有更适合云上的性能优化,提升运行效率。客户的需求大致如下:

  • 任务全部是 Spark SQL,在 IDC 中运行时间大约1小时;

  • 能兼容线下的调度方式,在 IDC 中支持 SQL 和 Shell 两种提交方式;

  • 最终结果数据可以继续和线下数据无缝交互。

一、方案选择

考虑到对线下调度系统的兼容性,选择了 Amazon EMR : Amazon EMR 本身和线下 Hadoop 较为接近,客户上手更快;  Amazon EMR 可以通过多种方式直接提交 Spark SQL ,不需要经过转换或者封装;以及给客户提供了 Spark,Hive,甚至 Presto 等更多的选择;同时还提供了对 Spot Instance 的支持,降低成本。

4221fc23ec55108966519d6c813e73a5.png

二、方案架构

架构说明:我们将整个架构无缝集成入客户的调度系统中,包含了数据,代码,流程三部分。

  • 所有的数据和代码都存放在 Amazon S3 上,流程存放在客户的调度系统里,所以 Amazon EMR 是一个无状态的计算服务,每日动态启动,完成当天的 ETL 工作之后,再终止掉该集群,最大化发挥云上的弹性优势;

  • 和客户的调度系统集成 Amazon EMR 的启动脚本,封装成 Shell,并记录下集群 id ;附录1提供了 Amazon EMR 提交任务的几种方式供参考;

  • 通过客户调度系统,往该集群 id 提交 Steps 的方式提交 Spark SQL 脚本,并给调度系统返回 Steps 的执行日志;这里我们选择了更云原生的 Steps 提交方式;

  • 最终确认所有的任务执行完毕,通过客户调度关闭集群。

三、方案实施

  1. 存储:新建 Amazon S3 Bucket 和 prefix ,将所有的数据和依赖包和输出放在上面;

  2. 元数据管理:IDC 中一般使用 MySQL 作为后端的 Hive Metastore ,但我们云上优先选择托管的 Amazon Glue 元数据目录服务,主要好处有两点:免于管理运维;成本较 MySQL 更为低廉;

  3. 计算:考虑到性能,优先选择 Amazon EMR 5.32之后的版本,亚马逊云科技的服务团队为我们带来了大量的 Spark 和 Hive 性能调优;但考虑到兼容性,此次并没有选择使用了 Hadoop 3/Hive 3/Spark 3的 Amazon EMR 6.2.0,降低了迁移成本,最终选择了 Amazon EMR 5.33.0作为本次上云的最终版本。当然, 由于在第一步和第二步已经做到了存算分离,后续我们可以随时同步跟随 Amazon EMR 升级的步伐,获取更好的性能和特性而不需要任何额外的负担和成本;

  4. 机型选择:根据到客户的任务性质和数据量,选择单 Master 方案,Master Node 为 r5d.2xlarge 一台,Core Node 为 r5d.12xlarge两台;最终每天所有 ETL 任务跑完的费用只需要3-5美元。

  5. 集群建立:shell 封装;

  6. 任务提交:Amazon EMR Steps 提交方式,使用 shell 封装;提交任务的代码已经上传在 github:https://github.com/hades1712/EMR_Steps

  7. UDF 嵌入:一般用户会在提交查询语句的时候注册临时 UDF ,临时的UDF并不能在集群起停整个生命周期保留,所以在集群创建后将 UDF 统一上传到 Amazon S3,进行统一注册:

create function if not EXISTS xxx as "UDF_name" USING JAR 's3://s3_UDF.jar_URL'

*左滑查看更多

四、方案测试

我们将所需要的原始数据同步上了 Amazon S3 的目录,准备测试工作。在测试中发觉从线下迁上来任务可能存在一些小问题,主要有两个:

  1. UDF 注册:在线下 IDC 可能是数据平台完成的,但线上我们需要上传到 Amazon S3 并在任务 SQL 文件中声明;

  2. SQL 改造:这个也是有些意外的,大部分客户平台会弥补一些小的细节,迁移上云之后我们在创建临时表的时候增加了 DROP table if EXIST 的语句来避免报错,增加任务的幂等性。

最终将任务都搬上云后,我们测试了所有的任务,其中运行时间最长的任务从35分钟缩短到了25分钟左右,体现了云上的优势。

五、方案优化

亚马逊云科技在 Amazon EMR 上对 Spark 做了包含写入优化器,AQE 等不同的优化,有些来自开源社区,有些是亚马逊云科技针对云上产品特性定制开发的。虽然目前整体的任务时间已经从一个小时以上缩短了20%,但我们希望能给客户在云上更好的体验,参考亚马逊云科技已经做的这些特性,对客户任务做进一步的优化。

首先,我们从输出入手。客户的任务已经在存储格式上选择了 ORC 这样针对数据仓库优化的列式存储,能观察到在执行过程中,Amazon EMR 上的 Spark 针对ORC 启用了 DFOC 这样的优化型输出:由于 Amazon S3 和 HDFS 不一样,对象存储会把 mv 操作变成一系列的 copy-delete ,导致在 HDFS 上原本秒级的操作会放大到分钟级别,同时在任务强度不大的情况下闲置大量计算资源,但 Amazon EMR 5.32开始我们针对 Spark 输出 ORC 做了优化, DirectFileOutputCommitter 会直接使用 Amazon S3 Multipart-Upload 的技术将 copy-delete 变成 finalize 文件,把时间从分钟级别变回秒级,提升任务运行速度和资源利用率。

虽然 Amazon EMR Spark DFOC已经缩短了很多等待时间,但在检查输出文件的时候我们发觉了大量的小文件,重复跑了几次发觉最终输出都是1000个左右 KB 级别的文件,不管是对于 HDFS 还是 Amazon S3,我们都建议把单个文件的大小落在 MB 级别,最好是64-128 MB 。但 Spark 调整输出的参数是 Spark 3.0 开始才正式引入的功能,如何在 Spark 2.4.7 上调整呢?

其实 Amazon EMR 一直在改进 Spark 的运行效率,很早就开始引如 Amazon EMR Spark Runtime 和 Amazon EMR S3-optimized committer 这样的特性。从 Amazon EMR 5.32 开始,更是把 Spark  3.0 上的 Adaptive Query Engine 移植到 Amazon EMR 5 系列上的 Spark 2.4上,我们找到了 Spark 3.0 上的分区大小和数量的参数,根据客户的任务做了一些调整,打开动态调整的特性,并将分区数和分区大小分别调整为 100 和 128MB :

set spark.sql.adaptive.enabled=true;
set spark.sql.adaptive.coalescePartitions.enabled=true;
set spark.sql.adaptive.advisoryPartitionSizeInBytes=134217728;
set spark.sql.shuffle.partitions=100;

*左滑查看更多

再次执行任务后,输出文件降低到200个左右,并且任务时间也随之降低到了20分钟以内。第一次优化目标达成。

但最后在检查集群整体使用率的时候发觉另一个问题,我们把集群内存资源和运行时长乘积之后和所有任务的执行 GB*seconds 比较,有巨大的差异,如果光看数据,集群的利用率还不到30%,对于大数据来说是不可接受的,于是决定开始第二次优化。

重新检查了所有运行日志,发现日志中间出现了好几次 rename 的阶段,最长的一次甚至超过了5分钟,在 rename 阶段,整个集群都处于空闲状态。仔细检查了任务中的所有环节,原来问题在临时表,这个任务执行过程中会产生好几张临时表,这些临时表全部都是内表,且没有任何文件格式指定,导致了其实这些中间表都是以文本格式输出到 Amazon S3 上。

既然找到了问题所在,那么我们就可以继续第二次优化。在保证输入和输出的格式不变,和客户线下的 ETL 流程维持兼容的情况下,我们引入了 Parquet 作为中间表的存储格式,使用 Amazon EMR S3-optimized committer 的特性,看看是否能带来性能提升。仍然选择最长的任务作为实验对象,将左右的临时表建表语句变成 CREATE table USING Parquet ;

再次执行任务之后,观察运行状况,能看到所有 rename 阶段都已经去掉。实际这个任务能稳定在5分钟内完成,和原来 IDC 中35分钟比起来,获得了令人满意的进步,并且所有的改动几乎没有造成客户上云额外的代码变更和验证。

六、方案总结

Amazon EMR 在保证了对线下 Hadoop 兼容的情况下,很好的引入了存算分离的架构:集中式的数据存储(Data and Raw Data)和集中式的元数据管理(Meta Data),具备了以下几大特点:

  1. 使用无状态的 Amazon EMR,极大的降低了每日使用的成本;

  2. 未来的升级方案和路径也很清晰,易于跟进新技术而不受到存储的限制;

  3. 保证了对开源产品的兼容性在使用,但又在 Amazon EMR 上引入大量的性能优化,包括对于Parquet写入的性能优势非常明显,值得大家升级。

大量从云下的 Hive或者 Spark SQL 迁移上云,只需要简单通过存算分离的 Amazon EMR + Amazon S3 架构,并把迁移重点放在数据格式,中间临时表的状态,就可以便捷快速的完成迁移任务,获得巨大的性能提升,同时具备面向未来的架构无限升级可能性。

附录

Amazon EMR 任务提交方式:https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-commandrunner.html

Amazon EMR 优化写入器:https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-s3-optimized-committer.html

Spark 性能优化:https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-performance.html

本篇作者

9a6c18a54dc2bf763dec33d86d470c44.png

翟羽翔

亚马逊云科技解决方案架构师

负责基于亚马逊云科技云计算方案的架构咨询和设计实现,同时致力于数据湖的应用和推广。

860512683af013817736dad479cd1c2a.png

董仕超

亚马逊云科技解决方案架构师

负责基于亚马逊云科技的云计算方案架构的咨询和设计,致力于亚马逊云科技云服务在国内和全球的应用和推广,在加入 亚马逊云科技 前,拥有多年外企售前及运营商 IT 架构、运维经验。

dengdengdeng~🔔又到了开奖环节啦~

恭喜以下五位小伙伴获得本次抽奖的奖品!👏

06fa6eed62c405e5bc5e36ee26b5d8be.png

我们会尽快寄出礼品

亚马逊云科技也会一直给大家带来惊喜~

大家不要错过哦!

a703ecbd59e384d64fa636992b4f080e.png

扫描上方二维码即刻报名

571a176a9329b948307502ed15038df6.gif

8b6de8c241e5e4bda7dab1e7168c2e95.gif

听说,点完下面4个按钮

就不会碰到bug了!

3d23e66ffa8fc7635d09edbc039b4509.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值