Presto在滴滴的探索与实践


桔妹导读:Presto在滴滴内部发展三年,已经成为滴滴内部Ad-Hoc和Hive SQL加速的首选引擎。目前服务6K+用户,天天读取2PB ~ 3PB HDFS数据,处理30万亿~35万亿条记录,为了承接业务及丰富使用场景,滴滴Presto须要解决稳定性、易用性、性能、成本等诸多问题。咱们在3年多的时间里,作了大量优化和二次开发,积攒了很是丰富的经验。本文分享了滴滴对Presto引擎的改进和优化,同时也提供了大量稳定性建设经验。html




1. 
Presto简介
1.1 简介

Presto是Facebook开源的MPP(Massive Parallel Processing)SQL引擎,其理念来源于一个叫Volcano的并行数据库,该数据库提出了一个并行执行SQL的模型,它被设计为用来专门进行高速、实时的数据分析。Presto是一个SQL计算引擎,分离计算层和存储层,其不存储数据,经过Connector SPI实现对各类数据源(Storage)的访问。


1.2 架构


Presto沿用了通用的Master-Slave架构,一个Coordinator,多个Worker。Coordinator负责解析SQL语句,生成执行计划,分发执行任务给Worker节点执行;Worker节点负责实际执行查询任务。Presto提供了一套Connector接口,用于读取元信息和原始数据,Presto 内置有多种数据源,如 Hive、MySQL、Kudu、Kafka 等。同时,Presto 的扩展机制容许自定义 Connector,从而实现对定制数据源的查询。假如配置了Hive Connector,须要配置一个Hive MetaStore服务为Presto提供Hive元信息,Worker节点经过Hive Connector与HDFS交互,读取原始数据。


1.3 实现低延时原理

Presto是一个交互式查询引擎,咱们最关心的是Presto实现低延时查询的原理,如下几点是其性能脱颖而出的主要缘由:

  • 彻底基于内存的并行计算
  • 流水线
  • 本地化计算
  • 动态编译执行计划
  • 当心使用内存和数据结构
  • GC控制
  • 无容错



2. 
Presto在滴滴的应用
2.1 业务场景

  • Hive SQL查询加速
  • 数据平台Ad-Hoc查询
  • 报表(BI报表、自定义报表)
  • 活动营销
  • 数据质量检测
  • 资产管理
  • 固定数据产品



2.2 业务规模



2.3 业务增加



2.4 集群部署


目前Presto分为混合集群和高性能集群,如上图所示,混合集群共用HDFS集群,与离线Hadoop大集群混合部署,为了防止集群内大查询影响小查询, 而单独搭建集群会致使集群太多,维护成本过高,咱们经过指定Label来作到物理集群隔离(详细后文会讲到)。而高性能集群,HDFS是单独部署的,且能够访问Druid, 使Presto 具有查询实时数据和离线数据能力。


2.5 接入方式

二次开发了JDBC、Go、Python、Cli、R、NodeJs 、HTTP等多种接入方式,打通了公司内部权限体系,让业务方方便快捷的接入 Presto 的,知足了业务方多种技术栈的接入需求。

Presto 接入了查询路由 Gateway,Gateway会智能选择合适的引擎,用户查询优先请求Presto,若是查询失败,会使用Spark查询,若是依然失败,最后会请求Hive。在Gateway层,咱们作了一些优化来区分大查询、中查询及小查询,对于查询时间小于3分钟的,咱们即认为适合Presto查询,好比经过HBO(基于历史的统计信息)及JOIN数量来区分查询大小,架构图见:




3. 
引擎迭代


咱们从2017年09月份开始调研Presto,经历过0.19二、0.215,共发布56次版本。而在19年初(0.215版本是社区分家版本),Presto社区分家,分为两个项目,叫PrestoDB和PrestoSQL,二者都成立了本身的基金会。咱们决定升级到PrestoSQL 最新版本(340版本)缘由是:

  • PrestoSQL社区活跃度更高,PR和用户问题可以及时回复
  • PrestoDB主要主力仍是Facebook维护,以其内部需求为主
  • PrestoDB将来方向主要是ETL相关的,咱们有Spark兜底,ETL功能依赖Spark、Hive



4. 
引擎改进
在滴滴内部,Presto主要用于Ad-Hoc查询及Hive SQL查询加速,为了方便用户能尽快将SQL迁移到Presto引擎上,且提升Presto引擎查询性能,咱们对Presto作了大量二次开发。同时,由于使用Gateway,即便SQL查询出错,SQL也会转发到Spark及Hive上,因此咱们没有使用Presto的Spill to Disk功能。这样一个纯内存SQL引擎在使用过程当中会遇到不少稳定问题,咱们在解决这些问题时,也积累了不少经验,下面将一一介绍:


4.1 Hive SQL兼容

18年上半年,Presto刚起步,滴滴内部不少用户不肯意迁移业务,主要是由于Presto是ANSI SQL,与HiveQL差距较大,且查询结果也会出现结果不一致问题,迁移成本比较高,为了方便Hive用户能顺利迁移业务,咱们对Presto作了Hive SQL兼容。而在技术选型时,咱们没有在Presto上层,即没有在Gateway这层作SQL兼容,主要是由于开发量较大,且UDF相关的开发和转换成本过高,另外就是须要多作一次SQL解析,查询性能会受到影响,同时增长了Hive Metastore的请求次数,当时Hive Metastore的压力比较大,考虑到成本和稳定性,咱们最后选择在Presto引擎层上兼容。

主要工做:

  • 隐式类型转换
  • 语义兼容
  • 语法兼容
  • 支持Hive视图
  • Parquet HDFS文件读取支持
  • 大量UDF支持
  • 其余

Hive SQL兼容,咱们迭代了三个大版本,目前线上SQL经过率97~99%。而业务从Spark/Hive迁移到Presto后,查询性能平均提高30%~50%,甚至一些场景提高10倍,Ad-Hoc场景共节省80%机器资源。下图是线上Presto集群的SQL查询经过率及失败缘由占比,'null' 表示查询成功的SQL,其余表示错误缘由:



4.2 物理资源隔离

上文说到,对性能要求高的业务与大查询业务方混合跑,查询性能容易受到影响,只有单独搭建集群。而单独搭建集群致使Presto集群太多,维护成本过高。由于目前咱们Presto Coordinator尚未遇到瓶颈,大查询主要影响Worker性能,好比一条大SQL致使Worker CPU打满,致使其余业务方SQL查询变慢。因此咱们修改调度模块,让Presto支持能够动态打Label,动态调度指定的 Label 机器。以下图所示:


根据不一样的业务划分不一样的label,经过配置文件配置业务方指定的label和其对应的机器列表,Coordinator会加载配置,在内存里维护集群label信息,同时若是配置文件里label信息变更,Coordinator会定时更新label信息,这样调度时根据SQL指定的label信息来获取对应的Worker机器,如指定label A时,那调度机器里只选择Worker A 和 Worker B 便可。这样就能够作到让机器物理隔离了,对性能要求高的业务查询既有保障了。


4.3 Druid Connector

使用 Presto + HDFS 有一些痛点:

  • latency高,QPS较低 
  • 不能查实时数据,若是有实时数据需求,须要再构建一条实时数据链路,增长了系统的复杂性
  • 要想得到极限性能,必须与HDFS DataNode 混部,且DataNode使用高级硬件,有自建HDFS的需求,增长了运维的负担

因此咱们在0.215版本实现了Presto on Druid Connector,此插件有以下优势:

  • 结合 Druid 的预聚合、计算能力(过滤聚合)、Cache能力,提高Presto性能(RT与QPS)
  • 让 Presto 具有查询 Druid 实时数据能力
  • 为Druid提供全面的SQL能力支持,扩展Druid数据的应用场景
  • 经过Druid Broker获取Druid元数据信息
  • 从Druid Historical直接获取数据
  • 实现了Limit下推、Filter下推、Project下推及Agg下推

在PrestoSQL 340版本,社区也实现了Presto on Druid Connector,可是此Connector是经过JDBC实现的,缺点比较明显:

  • 没法划分多个Split,查询性能差
  • 请求查询Broker,以后再查询Historical,多一次网络通讯
  • 对于一些场景,如大量Scan场景,会致使Broker OOM
  • Project及Agg下推支持不完善

详细架构图见:


使用了Presto on Druid后,一些场景,性能提高4~5倍。


4.4 易用性建设

为了支持公司的几个核心数据平台,包括:数梦、提取工具、数易及特征加速及各类散户,咱们对Presto作了不少二次开发,包括权限管理、语法支持等,保证了业务的快速接入。主要工做:

  • 租户与权限
    • 与内部Hadoop打通,使用HDFS SIMPLE协议作认证
    • 使用Ranger作鉴权,解析SQL使Presto拥有将列信息传递给下游的能力,提供用户名+数据库名/表名/列名,四元组的鉴权能力,同时提供多表同时鉴权的能力
    • 用户指定用户名作鉴权和认证,大帐号用于读写HDFS数据
    • 支持视图、表别名鉴权

  • 语法拓展
    • 支持add partition
    • 支持数字开头的表
    • 支持数字开头的字段

  • 特性加强
    • insert数据时,将插入数据的总行数写入HMS,为业务方提供毫秒级的元数据感知能力
    • 支持查询进度滚动更新,提高了用户体验
    • 支持查询能够指定优先级,为用户不一样等级的业务提供了优先级控制的能力
    • 修改通讯协议,支持业务方能够传达自定义信息,知足了用户的日志审计须要等
    • 支持DeprecatedLzoTextInputFormat格式
    • 支持读HDFS Parquet文件路径


4.5 稳定性建设

Presto在使用过程当中会遇到不少稳定性问题,好比Coordinator OOM,Worker Full GC等,为了解决和方便定位这些问题,首先咱们作了监控体系建设,主要包括:

  • 经过Presto Plugin实现日志审计功能
  • 经过JMX获取引擎指标将监控信息写入Ganglia
  • 将日志审计采集到HDFS和ES; 统一接入运维监控体系,将全部指标发到 Kafka;
  • Presto UI改进: 能够查看Worker信息,能够查看Worker死活信息

经过以上功能,在每次出现稳定性问题时,方便咱们及时定位问题,包括指标查看及SQL回放等,以下图所示,能够查看某集群的成功及失败SQL数,咱们能够经过定义查询失败率来触发报警:


在Presto交流社区,Presto的稳定性问题困扰了不少Presto使用者,包括Coordinator和Worker挂掉,集群运行一段时间后查询性能变慢等。咱们在解决这些问题时积累了不少经验,这里说下解决思路和方法。前端


根据职责划分,Presto分为Coordinator和Worker模块,Coordinator主要负责SQL解析、生成查询计划、Split调度及查询状态管理等,因此当Coordinator遇到OOM或者Coredump时,获取元信息及生成Splits是重点怀疑的地方。而内存问题,推荐使用MAT分析具体缘由。以下图是经过MAT分析,得出开启了FileSystem Cache,内存泄漏致使OOM。web



这里咱们总结了Coordinator常见的问题和解决方法:

  • 使用HDFS FileSystem Cache致使内存泄漏,解决方法禁止FileSystem Cache,后续Presto本身维护了FileSystem Cache
  • Jetty致使堆外内存泄漏,缘由是Gzip致使了堆外内存泄漏,升级Jetty版本解决
  • Splits太多,无可用端口,TIME_WAIT过高,修改TCP参数解决
  • JVM Coredump,显示"unable to create new native thread",经过修改pid_max及max_map_count解决
  • Presto内核Bug,查询失败的SQL太多,致使Coordinator内存泄漏,社区已修复

而Presto Worker主要用于计算,性能瓶颈点主要是内存和CPU。内存方面经过三种方法来保障和查找问题:

  • 经过Resource Group控制业务并发,防止严重超卖
  • 经过JVM调优,解决一些常见内存问题,如Young GC Exhausted
  • 善用MAT工具,发现内存瓶颈

而Presto Worker常会遇到查询变慢问题,两方面缘由,一是肯定是否开启了Swap内存,当Free内存不足时,使用Swap会严重影响查询性能。第二是CPU问题,解决此类问题,要善用Perf工具,多作Perf来分析CPU为何不在干活,看CPU主要在作什么,是GC问题仍是JVM Bug。以下图所示,为线上Presto集群触发了JVM Bug,致使运行一段时间后查询变慢,重启后恢复,Perf后找到缘由,分析JVM代码,可经过JVM调优或升级JVM版本解决:


这里咱们也总结了Worker常见的问题和解决方法:

  • Sys load太高,致使业务查询性能影响很大,研究jvm原理,经过参数(-XX:PerMethodRecompilationCutoff=10000 及 -XX:PerBytecodeRecompilationCutoff=10000)解决,也可升级最新JVM解决
  • Worker查询hang住问题,缘由HDFS客户端存在bug,当Presto与HDFS混部署,数据和客户端在同一台机器上时,短路读时一直wait锁,致使查询Hang住超时,Hadoop社区已解决
  • 超卖致使Worker Young GC Exhausted,优化GC参数,如设置-XX:G1ReservePercent=25 及 -XX:InitiatingHeapOccupancyPercent=15
  • ORC太大,致使Presto读取ORC Stripe Statistics出现OOM,解决方法是限制ProtoBuf报文大小,同时协助业务方合理数据治理
  • 修改Presto内存管理逻辑,优化Kill策略,保障当内存不够时,Presto Worker不会OOM,只须要将大查询Kill掉,后续熔断机制会改成基于JVM,相似ES的熔断器,好比95% JVM 内存时,Kill掉最大SQL


4.6 引擎优化及调研

做为一个Ad-Hoc引擎,Presto查询性能越快,用户体验越好,为了提升Presto的查询性能,在Presto on Hive场景,咱们作了不少引擎优化工做,主要工做:

  • 某业务集群进行了JVM调优,将Ref Proc由单线程改成并行执行,普通查询由30S~1分钟下降为3-4S,性能提高10倍+
  • ORC数据优化,将指定string字段添加了布隆过滤器,查询性能提高20-30%,针对一些业务作了调优
  • 数据治理和小文件合并,某业务方查询性能由20S下降为10S,性能提高一倍,且查询性能稳定
  • ORC格式性能优化,查询耗时减小5%
  • 分区裁剪优化,解决指定分区但获取全部分区元信息问题,减小了HMS的压力
  • 下推优化,实现了Limit、Filter、Project、Agg下推到存储层

18年咱们为了提升Presto查询性能,也调研了一些技术方案,包括Presto on Alluxio和Presto on Carbondata,可是这2种方案最后都被舍弃了,缘由是:

  • Presto on Alluxio查询性能提高35%,可是内存占用和性能提高不成正比,因此咱们放弃了Presto on Alluxio,后续可能会对一些性能要求敏感的业务使用
  • Presto on Carbondata是在18年8月份测试的,当时的版本,Carbondata稳定性较差,性能没有明显优点,一些场景ORC更快,因此咱们没有再继续跟踪调研Presto on Carbondata。 由于滴滴有专门维护Druid的团队,因此咱们对接了Presto on Druid,一些场景性能提高4~5倍,后续咱们会更多关注Presto on Clickhouse及Presto on Elasticsearch



5. 
总结

经过以上工做,滴滴Presto逐渐接入公司各大数据平台,并成为了公司首选Ad-Hoc查询引擎及Hive SQL加速引擎,下图能够看到某产品接入后的性能提高:算法



上图能够看到大约2018年10月该平台开始接入Presto,查询耗时TP50性能提高了10+倍,由400S下降到31S。且在任务数逐渐增加的状况下,查询耗时保证稳定不变。数据库


而高性能集群,咱们作了不少稳定性和性能优化工做,保证了平均查询时间小于2S。以下图所示:数组





6. 
展望
Presto主要应用场景是Ad-Hoc查询,因此其高峰期主要在白天,以下图所示,是网约车业务下午12-16点的查询,能够看到平均CPU使用率在40%以上。


可是若是看最近一个月的CPU使用率会发现,平均CPU使用率比较低,且波峰在白天10~18点,晚上基本上没有查询,CPU使用率不到5%。以下图所示:性能优化



因此,解决晚上资源浪费问题是咱们从此须要解决的难题。微信


同时,为了避免与开源社区脱节,咱们打算升级PrestoDB 0.215到PrestoSQL 340版本,届时会把咱们的Presto on Druid代码开源出来,回馈社区。网络



本文做者


滴滴Presto引擎负责人,负责带领引擎团队深刻Presto内核,解决在海量数据规模下Presto遇到的稳定性、性能、成本方面的问题。搜索引擎及OLAP引擎爱好者,公众号:FFCompute



关于团队数据结构



滴滴大数据架构部 OLAP & 检索平台组负责以 Elasticsearch、Clickhouse、Presto 及 Druid 为表明的 OLAP 引擎的内核级极致优化,为滴滴各个产品线提供稳定可靠的 PB 级海量数据的实时数据分析、日志检索、监控及即席查询服务。


博闻强识,招贤纳士,滴滴用广阔的舞台,在这里,等待你!



扫描了解更多岗位




延伸阅读



内容编辑 | Charlotte
联系咱们 | DiDiTech@didiglobal.com
   

本文分享自微信公众号 - 滴滴技术(didi_tech)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索