登录 / 注册
IT168大数据频道
IT168首页 > 大数据 > 大数据技术 > 正文

张翼:Spark SQL在携程的实践经验分享!

2018-11-29 09:17    it168网站 原创  作者: 赵钰莹 编辑: 赵钰莹

  【IT168 专稿】本文根据张翼老师在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有两个:

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

  实现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权限控制模式主要有四种:

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

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

  第三种是Storage Based Authorization in the Metastore Server

  最后一个是 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发布之后。

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

关键字: Hadoop , Spark
  • IT168企业级IT168企业级
  • IT168文库IT168文库

扫一扫关注

  • 推荐文章
  • 推荐产品
行车视线文章推荐

首页 评论 返回顶部