查看原文
其他

干货 | 携程Presto技术演进之路

张巍 携程技术中心 2019-05-02

作者简介

 

张巍,携程技术中心大数据资深研发工程师。2017年加入携程,在大数据平台部门从事基础框架的研发和运维,目前主要负责 Presto,Kylin,StructedStreaming 等大数据组建的运维,优化,设计及调研工作。对资源调度,OLAP引擎,存储引擎等大数据模块有浓厚的兴趣, 对 hdfs,yarn,presto,kylin,carbondata 等大数据组建有相关优化和改造经验。


一、背景介绍


携程作为中国在线旅游的龙头,提供酒店,机票,度假等服务,这些服务的背后是基于各个部门每天对海量数据的分析。

 

随着业务的不断增长,用户体验的不断提升,每个部门对数据处理的响应时间要求越来越短,对各个部门报表的响应速度要求越来越快,对跨部门的数据交互和查询也越来越紧密,所以需要一个统一的快速查询引擎,且这个查询引擎需要从GB到PB以上的海量数据集中获取有价值的信息。

 

我们在技术选型上对比了Presto,Spark,Impala等MPP数据库。综合考量框架本身性能和社区活跃程度,最终选择了Presto。

 

Presto是Facebook开源的MPP数据库,先简单了解下架构图:

 

它是一个Master-Slave的架构,由下面三部分组成:

 

  • 一个Coordinator节点

  • 一个Discovery Server节点

  • 多个Worker节点

 

Coordinator负责解析SQL语句,生成执行计划,分发执行任务给Worker节点执行。


Discovery Server通常内嵌于Coordinator节点中。


Worker节点负责实际执行查询任务以及负责与HDFS交互读取数据。

 

Worker节点启动后向DiscoveryServer服务注册,Coordinator从DiscoveryServer获得可以正常工作的Worker节点。如果配置了HiveConnector,需要配置一个Hive MetaStore服务为Presto提供Hive元信息。

 

二、携程Presto使用的困境


首先来看一下我们2018年前遇到的一些问题。

 

携程在2014年探索使用Presto去满足用户快速即席查询和报表系统的需求。在2017年末,离线团队接手携程Presto后,发现当时的Presto本身存在一系列问题,那个时候Presto的版本是0.159,也相对较低。

 

稳定性差


  • 当时用户反馈最多的是,Presto又OOM了。只能采取重启Presto恢复服务,实际上对于用户来说,系统挂掉是最恶劣的一种体验了。


  • Presto严格的分区类型检查和表类型检查,导致大量用户在Presto上发起的查询以失败告终,对于那些使用老分区重新刷数据的用户简直就是灾难。


  • 一些大数据量的查询经常占用着计算资源,有时运行了2、3个小时,累计生成上百万个split,导致其他小的查询,响应速度受到严重影响。

 

认证不规范

 

  • 很早以前,携程在Presto中内部嵌入一个Mysql的驱动, 通过在Mysql表中存放用户账号和密码访问Presto的权限认证。实际上和大数据团队整体使用Kerberos的策略格格不入。

 

性能浪费 
  • 所有的join查询默认都是使用Broadcast join,用户必须指定join模式才能做到Broadcast join 和 Map join的切换。


  • 数据传输过程中并没有做压缩,从而带来网络资源的极大浪费。

 

没有监控


  • Presto自身没有监控分析系统,只能通过Presto自身提供的短时监控页面看到最近几分钟的用户查询记录,对分析和追踪历史错误查询带来很大的不便。


  • 无法知道用户的查询量和用户的查询习惯,从而无法反馈给上游用户有效的信息,以帮助应用层开发人员更合理的使用Presto引擎。

 

三、携程Presto引擎上所做的改进


为了提供稳定可靠的Presto服务,我们在性能,安全,资源管控,兼容性,监控方面都做了一些改动,以下列出一些主要的改进点。

 

性能方面


  • 根据Hive statistic信息,在执行查询之前分析hive扫描的数据,决定join查询是否采用Broadcast join还是map join。

  • Presto Page在多节点网络传输中开启压缩,减少Network IO的损耗,提高分布计算的性能。

  • 通过优化Datanode的存储方式,减少presto扫描Datanode时磁盘IO带来的性能影响。

  • Presto自身参数方面的优化。

 

安全方面


  • 启用Presto Kerberos模式,用户只能通过https安全协议访问Presto。

  • 实现Hive Metastore Kerberos Impersonating 功能。

  • 集成携程任务调度系统(宙斯)的授权规则。

  • 实现Presto客户端Kerberos cache模式,简化Kerberos访问参数,同时减少和KDC交互。

 

资源管控方面


  • 控制分区表最大查询分区数量限制。

  • 控制单个查询生成split数量上限, 防止计算资源被恶意消耗。

  • 自动发现并杀死长时间运行的查询。

 

兼容性方面


  • 修复对Avro格式文件读取时丢失字段的情况。

  • 兼容通过Hive创建 view,在Presto上可以对Hive view 做查询。(考虑到Presto和Hive语法的兼容性,目前能支持一些简单的view)。

  • 去除Presto对于表字段类型和分区字段类型需要严格匹配的检测。

  • 修复Alter table drop column xxx时出现ConcurrentModification问题。


四、携程Presto升级之路


升级之初Presto 的使用场景如图。


 

第一阶段,版本升级


对于版本选择,我们关心的几个问题:1)是否很好地解决各类内存泄漏的问题;2)对于查询的性能是否有一定提升。


综上考虑,决定使用0.190版本的Presto作为目标的升级版本。


通过这个版本的升级,结合对Presto的一部分改进,解决了几个主要问题:


  • Presto内存泄漏问题。

  • Presto读取Avro文件格式存在字段遗漏的问题。

  • Presto语法上无法支持整数类型相乘。

 

第二阶段,权限和性能优化


在第二个版本中,我们主要解决了以下问题:


  • Kerberos替换Mysql

  • Join模式的自动感知和切换

  • 限流(拒绝返回100万以上数据量的查询)

 

认证机制


这里简单介绍下Kerberos权限替换过程中的一些细节。


Presto的认证流程:



Presto 涉及到认证和权限的部分如上面红色框标注的3个部分,Coordinator, HDFS和Hive Metastore这三块。Coordinator和HDFS这两块是比较完善的,重点讲一下Hive Metastore。


在Kerberos模式下,所有SQL都是用Presto的启动账号访问Hive Metastore,比如使用Hive账号启动Presto,不论是flt账户还是htl账户提交SQL,最终到Hive Metastore层面都是Hive账号,这样权限太大,存在安全风险。我们增加了Presto Hive MetastoreImpresonating机制,这样htl在访问Hive Metastore时使用的是通过Hive账号伪装的htl账户。


 

新的问题又来了,在认证过程中需要获取Hive的Token, 可是Token反复的获取都需要一次Metastore的交互,这样会给Metastore带来压力。于是我们对Token 做了一个缓存,在其Token有效期内缓存在Presto内存中。

 

第三阶段,资源管控和监控平台


在第三个版本中,我们解决了以下问题:


  • 拦截大量生成split的查询SQL

  • Presto监控平台初步搭建

  • 限制最大访问的分区数量


数据采集


流程图

 

程序每一分钟从Presto Coordinator采集数据, 分发到多个监听器,同时写入Mysql表。


当前入库5张监控表。


Basic query:查询基本信息(状态,内存使用,总时间消耗,错误信息等)


Query stats:查询性能信息(每一步的时间消耗,数据输入输出量信息等)


Query info:查询客户端参数信息(发起客户的基本信息,参数信息等)


Query stage info:每个查询中所有stage的信息(输入输出量信息,内存使用情况,调用核的数量等)


Query task info:每个stage中所有task的信息(输入输出信息, 内存信息,调用核数等)

 

实时健康状况报告


基于以上采集的数据,我们会实时生成presto集群的健康报表以及历史运行趋势。这些数据可以用于:


  • 集群容量的评估

  • 集群健康状态的检测



问题追踪


除了健康报表之外,对于查询错误和性能问题,我们提供了详细的历史数据, 运维人员可以通过报表反应出的异常状况做进一步的排查。


通过报表能够发现某个用户查询时出现了外部异常



通过查看异常堆栈,发现查询是由于hive metastore出现短暂重启引起的查询失败。

 

其他


在Presto升级改进的同时,我们也调研了Presto on Carbondata的使用场景。


当时Carbondata使用的是1.3.0版本。在此基础上:


  • 修复了一系列Presto on carbon data 的功能和性能的问题

  • 对比了Presto on carbon data 和Presto on hive,得出结论:Presto on Carbon整体性能和Presto on orc的整体性能相当。同样的数据量Carbon snappy的存储是ORC zlib的六倍,就目前存储吃紧的情况下,不适合使用。

  • 目前仅在线上提供Carbondata 连接器,暂未投入业务使用。

 

当前Presto的架构为:


 

五、携程Presto未来升级方向


架构完善和技术改进


  • 启用Presto资源队列,规划通过AppName划分每个资源队列的最大查询并发数, 避免某个应用大量的查询并发同时被Presto执行,从而影响其他的App。


  • 实时告警平台,对于错误的查询,Presto能够实时的发送异常查询到告警平台,帮助运维人员快速响应和发现错误以便及时处理。


  • 统一的查询引擎,统一的查询引擎可以在presto,kylin,hive spark-sql之间匹配最优的查询引擎,做语法转换后路由过去。


业务方向


  • 未来携程内部OLAP报表系统(Art Nova) 会更大范围的采用携程Presto作为用户自定义报表的底层查询引擎,以用来提高报表的响应速度和用户体验。


  • 部分业务部门的vdp也计划调研,实时数据计算采用Presto作为其默认的查询引擎的可能性。

 

下个阶段我们期望的Presto整体架构图:



六、结束语


随着Presto社区的蓬勃发展,最新版本为0.203,其中包含了大量的优化和Bug Fix,希望跟大家一起讨论。


【推荐阅读】




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存