Presto 在字节跳动的内部实践与优化(实践篇)
在字节跳动内部,Presto 主要支撑了 Ad-hoc 查询、BI 可视化分析、近实时查询分析等场景,日查询量接近 100 万条。本文是字节跳动数据平台 Presto 团队-软件工程师常鹏飞在 PrestoCon 2021 大会上的分享整理,分两次连载。
在字节跳动内部,Presto 主要支撑了 Ad-hoc 查询、BI 可视化分析、近实时查询分析等场景,日查询量接近 100 万条。
功能性方面
完全兼容 SparkSQL 语法,可以实现用户从 SparkSQL 到 Presto 的无感迁移;
性能方面
实现 Join Reorder,Runtime Filter 等优化,在 TPCDS1T 数据集上性能相对社区版本提升 80.5%;
稳定性方面
首先,实现了多 Coordinator 架构,解决了 Presto 集群单 Coordinator 没有容灾能力的问题,将容灾恢复时间控制在 3s 以内。
其次实现了基于 histogram 的静态规则和基于运行时状态的动态规则,可以有效进行集群的路由和限流;
可运维性方面
实现了 History Server 功能,可以支持实时追踪单个 Query 的执行情况,总体观察集群的运行状况。
字节跳动 OLAP 数据引擎平台 Presto 部署使用情况
过去几年,字节跳动的 OLAP 数据引擎经历了百花齐放到逐渐收敛,再到领域细分精细化运营优化的过程。
存储方面离线数据主要存储在 HDFS,业务数据以及线上日志类数据存储在 MQ 和 Kafka。
计算引擎根据业务类型不同,Presto 支撑了 Ad-hoc 查询、部分 BI 报表类查询,SparkSQL 负责超大体量复杂分析及离线 ETL、Flink 负责流式数据清洗与导入。
为了处理日益增长的 Ad-hoc 查询需求,在 2020 年,字节跳动数据平台引入 Presto 来支持该类场景。
目前,整个 Presto 集群规模在几万 core,支撑了每天约 100 万次的查询请求,覆盖了绝大部分的 Ad-hoc 查询场景以及部分 BI 查询分析场景。
图注:字节跳动内部 Presto 集群部署架构图
上图是字节跳动内部 Presto 集群部署的架构,针对不同的业务需求拆分为了多个相互隔离的集群,每个集群部署多个 Coordinator,负责调度对应集群的 Worker。
接入层提供了统一的 Gateway,用以负责用户请求的路由与限流。同时还提供了 History Server,Monitor System 等附属组件来增加集群的可运维性与稳定性。
Presto 集群稳定性和性能提升
针对不同的业务场景以及查询性能要求,我们将计算资源拆分为了相互独立的 Presto 集群。
Gateway 负责处理用户请求的路由,这部分功能主要通过静态的路由规则来实现,路由规则主要包括允许用户提交的集群以及降级容灾的集群等。
为了更好的平衡不同集群之间的负载情况,充分有效的利用计算资源,后期又引入了动态的路由分流策略。该策略在做路由选择的过程中会调用各个集群 Coordinator 的 Restful API 获取各个集群的负载情况,选择最优的集群进行路由调度。
通过静态规则与动态策略相结合的方式,Gateway 在为用户提供统一接入接口的情况下,也保证了集群之间工作负载的平衡。
Coordinator 节点是单个 Presto 集群的核心节点,负责整个集群查询的接入与分发,因此它的稳定性直接影响到整个集群的稳定性。
在最初的部署中,每个 Presto 集群只能部署一个 Coordinator,当该节点崩溃的时候,整个集群大概会消耗几分钟的不可用时间来等待该节点的自动拉起。
为了解决这个问题,我们开发了多 Coordinator 的功能。该功能支持在同一个 Presto 集群中部署多个 Coordinator 节点,这些节点相互之间处于 active-active 备份的状态。
主要实现思路是将 Coordinator 和 Worker 的服务发现使用 Zookeeper 来进行改造。
Worker 会从 Zookeeper 获取到现存的 Coordinator 并随机选取一个进行心跳上报,同时每个 Coordinator 也可以从 Zookeeper 感知到其他 Coordinator 的存在。
每个 Coordinator 负责存储当前连接到的 Worker 的任务负载情况以及由它调度的查询执行情况,同时以 Restful API 的形式将这些信息暴露出去;其他 Coordinator 在做任务调度的时候会通过这些 Restful API 获取到整个集群的资源使用情况进行相应的任务调度。
目前多 Coordinator 机制已经在集群中上线使用了半年,将集群的不可用时间从几分钟降低到 3s 以内。
另一个影响 Presto 集群稳定性的重要因素是超大规模的查询。
在 Ad-hoc 场景下,这种查询是无法避免的,并且由于这种查询会扫描非常多的数据或者生成巨大的中间状态,从而长期占用集群的计算资源,导致整个集群性能下降。
为了解决这个问题,我们首先引入了基于规则以及代价的查询时间预测。
基于规则的查询时间预测主要会统计查询涉及到的输入数据量以及查询的复杂程度来进行预测。
基于代价的查询时间预测主要是通过收集在 Catalog 中的 Histogram 数据来对查询的代价进行预测。
上述预测能够解决部分问题,但是还是会存在一些预估不准的情况,为了进一步处理这些情况,我们引入了 Adaptive Cancel 功能。
该功能主要是在查询开始执行后,周期性的统计查询预计读取的数据量以及已完成的任务执行时间来预测查询整体的执行时间,对于预测超过阈值的查询提前进行取消,从而避免计算资源浪费,提升集群稳定性。
另外,Presto 本身提供的 UI 界面可以很好地对查询执行情况进行分析,但是由于这部分信息是存储在 Coordinator 内存当中,因此会随着查询数量的累积而逐步清除,从而导致历史查询情况无法获取。
为了解决这个问题,我们开发了 History Server 的功能。
Coordinator 在查询执行完成之后会将查询的执行情况存储到一个持久化存储当中,History Server 会从持久化存储当中加载历史的查询执行情况并提供与 Presto UI 完全相同的分析体验,同时基于这部分持久化的信息,也可以建立相应的监控看板来观测集群的服务情况。
本文中介绍的字节跳动内部 Presto 功能优化,目前已通过火山引擎数据产品“湖仓一体分析服务”向外部企业输出。
湖仓一体分析服务 LAS(Lakehouse Analytics Service)是面向湖仓一体架构的 Serverless 数据处理分析服务,提供一站式的海量数据存储计算和交互分析能力,完全兼容 Spark、Presto、Flink 生态,帮助企业轻松完成数据价值洞察。
更多关联产品
大数据研发治理套件 DataLeap
一站式数据中台套件,帮助用户快速完成数据集成、开发、运维、治理、资产、安全等全套数据中台建设,帮助数据团队有效的降低工作成本和数据维护成本、挖掘数据价值、为企业决策提供数据支撑。
火山引擎 E-MapReduce
支持构建开源 Hadoop 生态的企业级大数据分析系统,完全兼容开源,提供 Hadoop、Spark、Hive、Flink 集成和管理,帮助用户轻松完成企业大数据平台的构建,降低运维门槛,快速形成大数据分析能力。
欢迎关注字节跳动数据平台同名公众号
版权声明: 本文为 InfoQ 作者【字节跳动数据平台团队】的原创文章。
原文链接:【http://xie.infoq.cn/article/ef46f810f0d57fd14cd48b6e5】。文章转载请联系作者。
评论