Spark SQL在携程的实践经验分享

本文根据张翼老师在2018年5月13日【第九届中国数据库技术大会】现场演讲内容整理而成。

讲师简介:

张翼,10年互联网老兵;2015年3月加入携程,携程的大数据平台技术总监,带领团队构建稳定,高效的数据平台和系统,保证了携程数据的高速发展;加入携程之前,在大众点评负责数据基础架构,从0开始组建团队,搭建起点评的数据分析平台;平时关注与大数据及AI系统的发展,致力于将开源技术和公司场景相结合,创造业务价值。

摘要:

之前,大多数公司大数据的数仓都是构建在Hive上的,数据开发的ETL任务以及用户对于数据的即时查询主要使用的工具也是Hive,随着Spark以及其社区的不断发展,Spark及Spark SQL本身技术的不断成熟,Spark在技术架构和性能上都展示出Hive无法比拟的优势,如何使用Spark构建大数据的数仓?如何将现有的数仓平台从Hive转到Spark上?这些问题都是每家公司需要考虑的问题;携程原先的数仓也是构建在Hive之上的,每天运行超过20000个Hive的定时任务,从2017年9月份开始,我们正式启动了SparkSQL落地的一系列项目,到目前为止,大部分的ETL作业和用户的临时查询已经使用了SparkSQL;在这个演讲中,我将分享下我们在这段时间中的做法,实践和思考,我们遇到问题,以及我们的解决方案。

分享大纲:

1、平台简介

2、总体方案和效果

3、经验分享

4、未来展望

正文:

1、平台简介

首先介绍一下携程大数据平台总体架构:

如下图所示,底层是资源部署和运维监控,主要包括两部分:自动运维系统和监控系统;自动运维系统大大降低了我们运维的effort,也降低了运维操作出错的概率,是我们能在很少的运维人力投入的情况下维护大规模的集群;随着系统变大,各个相关系统增多,一个有效的监控能帮助我们及时发现问题,并尝试进行自动的处理,这个也能够大大提升运维的效率。

第二层是开源的大数据框架,主要分成两部分:分布式存储计算和实时框架,实时框架目前主要支持JStorm,Spark Streaming和Flink,其中Flink是今年新支持的;而分布式存储和计算框架这边,底层是Hadoop,ETL主要使用Hive和Spark,交互查询则会使用Spark,Presto和Kylin。

第三层是工具系统层,直接提供给BI同学或者业务用户,主要分为以下几部分:数据开发平台,包括日常使用的调度,数据传输,主数据以及数据质量系统;数据查询平台,主要包括报表系统Art nova和Adhoc查询系统;机器学习算法平台,包括一个基于Spark的MLlib图形化拖拽平台,以及基于Docker的GPU云平台,主要提供给数据算法科学家做模型训练使用;最后一块是实时数据平台Muise,通过一个系统提供对所有类型实时作业的发布,管理,监控和运维的功能。

本文重点介绍Spark SQL在携程数据开发和数据查询系统的落地实践过程,所以在平台简介部分我先简单介绍一下这两大块的系统:

数据开发系统运行在分布式存储计算框架之上,分布式存储和计算框架最下面一层是Hadoop,其上是Hive和Spark;开发平台Zeus主要由调度系统、主数据系统、传输系统以及数据质量系统四部分组成。目前,我们的集群规模在1300台左右,调度系统的Active任务数超过75000个,每天运行调度任务的实例超过13万个,换算成底层MapReduce任务数大约在30万左右,系统中的传输任务和ETL任务大约占比50%,在2017年Q4季度,我们内部绝大多数在使用Hive。

数据查询系统同样运行在分布式存储和计算框架之上,整个平台包含两部分——报表系统ArtNova和Adhoc查询;Adhoc系统每天的查询数载每天1万+,2017年Q4季度主要支持Hive和Presto;新建报表系统ART Nova在去年12月正式上线,设计初衷就考虑摒弃Hive,改用Spark SQL或者Presto做查询。

那么为什么我们要将数据平台的计算引擎从Hive转到SparkSQL来呢?

在对于Hive优缺点的分析中我们能够发现这个原因;Hive的优点是历史悠久,且稳定性有保证,已经被用户广泛接受。而Hive的缺点也很明显,第一,其计算效率相比新一代计算引擎,比如Spark、Presto等要慢得多,因为其HQL会转化为多个MR Job,MR Job之间需要进行数据落地,效率自然比不上纯内存RDD的Spark效率,把Hive转到新一代的计算引擎能够大幅度地提升平台的计算效率;第二,Hive的源代码结构比较混乱,了解需要花费一定时间,在其上进行优化的代价也比较大。

那么怎么来做呢?我们曾经考虑过2种候选方案:第一,更换Hive的执行引擎为Tez或者Spark,第二,更换一个能同时兼容Hive Table(读、写、权限等)并可保持HQL最大兼容性的计算引擎。很长一段时间,我们倾向于第一种候选方案,也就是Hive on Spark的方案

而SparkSQL 和Presto则被用来作为即时查询计算引擎 。但是,下面的原因使我们最终下决心拥抱SparkSQL,并把其作为整个查询和开发平台的主要引擎:

  • 2017下半年,和携程规模相当,甚至比携程规模小的互联网公司完成或已经开始SparkSQL的迁移,并取得了一些成果

  • SparkSQL的成熟,特别是2.2之后它的兼容性,稳定性,性能有很大的提升

  • Hive on Spark除了Uber外很少有其他的用例

  • Hive社区的衰落和Spark社区的繁荣

  • 时机,2017下半年,我们已经基本解决了Hadoop集群增长带来的稳定性问题,有精力做较大的项目

2、总体方案和效果

迁移SparkSQL的挑战主要体现在技术和团队两层面:

技术层面,最大的挑战是对于已经在运行的大量作业,我们需要考虑如何将迁移过程的影响降到最小,需要做到以下3点:

  • 第一点也是最重要的需要有灰度升级过程

  • 第二点是SQL语法尽量兼容Hive原有语法

  • 第三点是权限控制需要兼容Hive原有方式

第二大挑战是原有与Hive配套的大量周边设施需要改造,比如日志、Metrics收集、监控和告警系统以及Dr Elephant等作业分析系统。

团队层面,我们对SparkSQL源码以及Scala并不熟悉,缺乏较大改动经验。

基于上述原因,我们将整个迁移过程分为四个阶段:

第一阶段,集中力量解决Blocking技术问题,主要的Blocking Issue有两个:

  1. 将Hive权限控制机制移植到SparkSQL之上

  2. 实现Thrift Server的impersonation

通过这个过程熟悉Spark和Scala,积累技术实力。

第二阶段,在Adhoc查询平台开始初步尝试,由于是即席查询,如果失败,用户可人工覆盖到Hive,影响较小;后面也新的报表系统ArtNova中尝试使用;在这个过程中,我们修复了大量bug,积累了开发和运维经验。

第三阶段,改造开发平台,让整个平台支持灰度推送。

第四阶段,开发平台作业全面灰度升级,优化性能并处理遗留的长尾问题。

根据上述四个阶段,我们制定了迁移时间表:

截止到今年5月份,Adhoc查询工具中使用Spark SQL查询占比57%,Art Nova大约有52%使用了Spark SQL。开发平台的非数据传输作业大约52%使用了Spark SQL,差不多是两万多个,也可理解为原有Hive脚本已全部转成Spark SQL方式。转化完成,计算效率较之前提升了6-7倍。

3、经验分享

3.1 开发平台的灰度变更支持

首先分享我们在灰度变更部分的经验,这也是整个过程最重要的部分。我们最初在开发平台构建灰度变更机制是在Hive从0.13升级到1.1时,最开始仅支持环境变量等简单规则,在本次SparkSQL升级的过程中添加了执行engine / shell cmd变更规则等更多复杂的规则;系统支持变更组,也支持包括多种类型的变更策略:如全量推送,分作业优先级按照百分比推送,指定单个作业进行推送;最后一点是在作业失败后,fallback到当前默认配置的功能,这点对于作业稳定性保障至关重要。

一个典型的用户操作流程如下图所示:

我们在SparkSQL灰度升级时的实际配置如下:

Spark灰度升级引入了一种新的灰度升级规则 - engine,如上图所示,我们先在规则配置里设置一条使用SQL的引擎,即SparkSQL;我们配置了3条策略,对低优先级任务,当前的推送比例是100%,对高优先级任务,我们的推送比例是70%,并外我们还设置了一条Black List的策略,将遇到问题的作业暂时排除在推送之外

3.2 问题及其解决

在整个升级的过程中,我们遇到了很多问题,需有问题社区已经有了相关的解决方案(Apply社区Jira的修复超过30),还有很多问题需要我们自己解决,这边我分享下我们遇到的几个主要的问题:

1. 权限相关

  1.1 Hive权限落地

  1.2 Thrift Server Impersonation

2. 小文件合并

3. 资源利用率优化

Hive权限落地

Hive权限控制模式主要有四种:

  1. 在Hive 0.13版本之前,是Default Authorization,简称v1,当然官方文章上曾提及该版本存在一些问题

  2. 在Hive 0.13或者之后的版本中,提出的是 SQL Standards Based Hive Authorizatio,简称v2

  3. 第三种是Storage Based Authorization in the Metastore Server

  4. 最后一个是 Authorization using Apache Ranger & Sentry方式

由于携程使用Hive的历史比较长,所以我们主要使用的权限控制方式是第一种,在这个基础上对问题进行修复,比如grant无权限控制等问题等;考虑到未来的实际需求,Spark SQL也需要支持前两种权限控制方式。

我们对Spark code进行了修改以支持这两种权限控制的方式;Spark用到了很多Hive代码,最终通过ExternalCatalog调用HiveExternalCatalog执行 HiveClientImpl里的方法,在HiveClientImpl里,我们增加了权限检查方法,从而做到在Spark语句执行前检查在Hive中设置的权限;对于权限控制模式v2的话,实现非常简单,基本加一行code就可以;而权限控制模式v1相对来说复杂一点,需要把Hive的权限和相关逻辑全部移植过来。做法与v2相同,代码量大约在400行左右

Thrift Server Impersonation

Adhoc查询平台使用Thrift Server的方式执行SparkSQL,虽然其上的绝大多数操作是查询,但是也有少量的写操作,Thrift Server是以Hive账号启动的,如果没有用户账号的Impersonation,写的文件的Owner是Hive账号,但是我们希望的Owner是用户在Adhoc平台上选择的账号。

Hortonworks有自己的解决方案,Thrift Server只作为Proxy Server,在用户作业提交时再以其身份去启动AM和executor,以用户+connection id维度重用资源;这样做的问题是账号较多的情况下,executor的启停带来额外的开销。由于携程内部BU较多,每个BU使用的账号也非常多,这种方式可能对我们不是太适用。

我们采取的做法是在Thrift Server启动时预先启动AM和executor,将各账号keytab分配到各个nodemanager之上,然后在executor端真正执行Task时,使用超级账户把用户impersonate 成实际用户。

下图为详细技术图:

小文件问题

如果不做任何修改,Spark在写数据时会产生很多小文件;由于我们集群本身的存量文件就较多,Spark大量产生小文件的话,就会对NN产生很大的压力,进而带来整个系统稳定性的隐患,我们在灰度推送到30%(6000 Job / day)时发现不到3周的时间内就使NN的文件 + Block数飙升了近1亿,这个还是在每天有程序合并小文件的情况下;另外文件变小带来了压缩率的降低,数据会膨胀3-4倍。

修复的方法其实比较简单,在Insert Into Table或是Create Table as的情况下,如果本身没有RepartitionByExpression的话,就增加一个RepartitionByExpression的stage

下面是相关的代码:

在这之后,小文件问题就得到了控制,运行到目前为止还是比较正常的。

资源利用效率优化

上图橘色的图片是每个作业的平均时间,在红色边框的时间内没有明显变化,下方紫色的图片是整个集群的平均延迟,可以看到有30%的下降。虽然这个改动非常简单,但是对整体集群的资源利用效率有很大提升。

4、未来展望

近期工作

1. 继续推进SparkSQL在数据开发平台的使用比例,我们的目标是在5月底达到90%

目前纯粹的Hive的分析任务已经基本转换完成,剩余的主要任务是转换Legacy的Shell脚本中使用到Hive的地方,我们使用的方法是用函数的方式将hive直接替换为sparksql的command

2. 优化作业内存的使用,作业转到SparkSQL之后,对内存的使用量也急剧上升,在某些时间点出现了应用内存分配满而无法分配更多作业的情况,我们的解决思路有两个:

  • 根据作业历史的内存使用情况,在调度系统端自动设置合适的内存

  • https://issues.apache.org/jira/browse/YARN-1011

未来我们希望做2件事:

1. 能够进一步优化长尾的SparkSQL作业的性能;从Hive转换为SparkSQL之后,绝大多数作业的性能得到了较大的提高,但是还有有少量的作业运行效率反而下降了,也有一些作业出现运行失败的情况(目前都fallback到Hive),我们简单地统计了一下

  • 有2.5%左右的作业会出现失败(400~)

  • 有6%左右的作业运行效率接近或比Hive更差(1000~)

  • 有2.5%左右的作业运行时间比Hive慢5分钟以上

后续我们会针对上面这些问题作业的共性问题,进行研究和解决

2. 升级到Spark 2.3

积极跟进社区的步伐,调研,测试,适配Spark 2.3;当然正式的生产使用会放在Spark 2.3.1发布之后。

以上是我所有的分享,希望对大家有所帮助,谢谢!

本文来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31545816/viewspace-2221925/

新福利:

从11月01日开始至12月06日截止,一共五周时间,每周五我会从公众号选择阅读+转发综合最多的读者一名,免费包邮送实体新书《Flink入门与实战》,留言互动起来吧~

上周获奖名单:飛


猜你喜欢

1、Apache Spark 中编写可伸缩代码的4个技巧

2、ElasticSearch 亿级数据检索案例实战

3、Flink Forward Asia 2019 总结和展望 - 附PPT下载

4、58同城实时计算平台架构实践

过往记忆大数据微信群,请添加微信:fangzhen0219,备注【进群】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值