桔妹导读:Presto在滴滴外部倒退三年,曾经成为滴滴外部Ad-Hoc和Hive SQL减速的首选引擎。目前服务6K+用户,每天读取2PB ~ 3PB HDFS数据,解决30万亿~35万亿条记录,为了承接业务及丰盛应用场景,滴滴Presto须要解决稳定性、易用性、性能、老本等诸多问题。咱们在3年多的工夫里,做了大量优化和二次开发,积攒了十分丰盛的教训。本文分享了滴滴对Presto引擎的改良和优化,同时也提供了大量稳定性建设教训。
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.192、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。
这里咱们总结了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
滴滴技术 出品