网易基于历史查询的 Impala 集群性能优化实践
导读: 本文将介绍基于历史查询的 Impala 集群性能优化与实践。
分享嘉宾|温正湖 网易数帆 数仓技术负责人
编辑整理|谢小甲
出品平台|DataFunTalk
01 背景介绍
1. 网易数帆
网易数帆是网易旗下数字化转型技术与服务提供商,主要由网易轻舟、网易有数、网易易智和网易易测四部分组成。
2. 网易数帆中的网易有数
网易有数目前支撑了公司内部绝大部分互联网业务,包括音乐、严选、有道、邮箱、传媒等。我们也有很多外部商业化的客户,涵盖了金融、零售、农业、能源、物流等行业领域中的企业。
3.网易有数中 Impala 的定位和应用场景
网易有数大数据平台的基础设施中包含了主流的计算和查询系统,如下图所示。在这之中,Impala 主要是聚焦于交互式计算,主要应用场景包括有数 BI、自助取数和交互式查询等。
- 有数报表:BI 工程师可以通过敏捷 BI 进行数据分析
- 自助取数:无需写 SQL,采用拖拽式自助取数
- 交互式查询:可以通过 SQL 进行灵活的数据分析
02 高性能数仓建设
1. 为何要进行高性能数仓建设
网易大数据团队是国内最早一批将 Impala 作为分析型数仓查询引擎的团队,在长期的使用实践中,积累了丰富的集群运维、问题排查、特性增强和性能优化经验。在这个过程中,我们发现仅使用社区的 Impala 版本是不够的,如果没有进一步的增强和优化,会对业务造成不同程度的影响,主要涉及查询的性能和成功率,我们将业务痛点归类如下:
- 痛点一:混合型业务负载挑战
一个 Impala 集群可能服务整个大业务,比如网易云音乐拥有很多个部门,每一个部门会使用 Impala 做不同的事情,比如查询报表或进行 Ad-Hoc 查询或进行数据分析亦或仅仅是获取数据。这些不同类型的查询,在同一个 Impala 集群上可能会互相产生影响,比如资源竞争等。会导致部分业务的 SLA 无法保障。
- 痛点二:复杂/聚合查询性能****差
对于报表等 BI 类应用,其性能要求相比离线的任务会高很多,用户的耐受程度通常为秒级,一般要求 5 秒以内。但 BI 类应用的有些图表查询的数据量可能较大、数据连接和聚合等操作计算量较多,如此一来,定会比一般的查询性能更差一些。比如图表查询时间需要 10 秒以上,甚至数十秒,用户显然是不可接受的。
- 痛点三:统计信息缺失导致慢查询
收集统计信息在数据库领域属于一个比较大的技术难点。统计信息涉及到资源预估,以及执行计划的优化等。在 Hadoop 生态中的各查询引擎均没有较好解决统计信息的问题。很多查询引擎未提供统计信息的自动计算能力,就算提供了,统计信息的粒度也不够细。这会导致计算资源预估不准确,执行计划不够合理,比如大表作为build表或大表走broadcast而不是shuffle等,这都会引起查询性能变差。
- 痛点四:元数据缓存****和更新问题
Impala 提供了元数据缓存,通过在集群内部缓存表、列和文件级别元数据来提升查询性能,但同时也带来了一些问题。因为离线数据产出往往通过 Hive 或 Spark,Impala 无法感知到表元数据的变化,进而无法及时更新元数据缓存,导致查询时因使用旧的元数据而报错。
- 痛点五:存储层波动影响查询性能
Impala 是存算分离的设计架构,典型的使用场景是表元数据在 HMS 中,数据在远端的 HDFS 集群中。若不考虑 Impala 数据和元数据缓存,Impala 查询时,需要跨网络访问 HMS 和 HDFS 集群,容易因为网络、HMS、HDFS NN 或 DN 性能波动导致查询性能变差。如何消除这些波动降低对用户的影响就是一个很值得研究的问题。
- 痛点六:集群状态周期性腐化
时不时会有业务同学会问为什么这个查询性能越来越差了啊?我什么都没做。其实导致集群状态变差的原因很多,那怕都是执行相同的查询 SQL,但因为随着时间的变化,需要扫描和计算的数据量变多,也可能导致集群性能变差,比如计算资源竞争越来越严重、IO 波动变频繁等。当然,更普遍的情况是由于没有控制新业务/场景的接入,导致集群承接的查询越来越多,集群不堪重负。这需要我们及时识别集群状态恶化,找出问题的原因并尽早优化,以免影响 SLA。
2. 高性能数仓——建设原则
当然,上面所述的多种类型的问题,除了元数据缓存相关外,其他的都是普遍性问题,使用同类型的数仓查询引擎也可能会遇到。 为了有效解决包括 Impala 在内的大部分 Hadoop 查询引擎都存在的这些问题 , 我们提出基于 Impala 建设高性能数仓。 下面先简单说明高性能数仓的建设原则,再介绍上述问题的解决方案。
建设高性能数仓,最重要的就是要持续增强 Impala 的核心能力,其次是要充分利用历史查询信息。
在组件之间,可以进行上下游组件的垂直优化,例如:有数 BI 等组件通过 SQL 注解,反哺 Impala 进行更智能的查询分析。
此外,充分利用网易有数全链路大数据平台的优势,也是建设高性能数仓的另一个重要原则。
3. 高性能数仓——业务痛点解决方案
混合型业务负载上,我们引入了虚拟数仓,对业务进行物理资源隔离 。本质上虚拟数仓依旧在一个 Impala 集群上面,不同点在于是对物理资源进行了隔离。但在这种隔离条件下,会引起资源利用率变低的问题,这也是需要进行优化的。
在统计信息缺失导致慢查询的问题上,我们提供了统计信息自动计算的能力 。即便拥有统计信息,它的预估依然会存在较大可能不准的问题,所以我们进一步基于历史查询做查询 SQL 的归一化模版,用历史查询的实际内存消耗来提升查询的内部预估精度。
存储性能上,Impala 本身自带有本地缓存的能力,针对该内容, 我们做了进一步的增强。
复杂、聚合查询能力差,解决方式无非通过提升计算能力,在资源有限的情况下,尽量压榨计算性能。比如早期使用的 Ambari 集群部署,一个机器只能部署一个 Impalad,该机器的 CPU、内存资源无法充分利用,我们希望用户端可以部署多个节点。在高版本上,我们希望可以依托 Impala 多线程(MT_DOP)的能力,通过提升计算资源利用率来进一步提升查询效率。
03 HBO 实现方案
1. HBO 信息来源——Impala 管理服务器
HBO 即基于历史查询的优化。
在使用 Impala 的过程中,为了解决无法查看和审计集群中的查询等问题,我们引入了 Impala 管理服务器——Manager 组件。该组件的主要功能,是持久化保存Impala查过的那些 SQL,也会存储这些 SQL 的 Profile 信息,目前我们是将其保存在 MySQL 中。同时,对保存下来的信息,进行解析,实现结构化保存。
其实现原理如下: 开启后,Coordinators 会向 Statestore 注册查询信息,例如在Statestore 上会有一个新的 Topic,这个 Topic 里面会保存那些 Coordinators 有哪些查询记录,Manager 会从 Statestore 获取查询信息,包括 Hostname 以及 Query_ID,根据 Hostname 向对应的 Coordinator 发送 Http 请求指定 Query_ID 的查询信息并保存到 MySQL 中。
2. 历史查询信息解析
如图中所示,管理服务器提供了基础的查询信息,包括排队耗时、内存预估和实际消耗、扫描的数据量等。
此外,还保存了 Profile、Timeline 和 Summary 信息。这样,就可以排查存在性能问题的历史查询。
如左图,我们通过解析 Profile 文件,我们可以看查询的执行计划,分析是否可以进行优化,右图中具体展示了 Scan Node 的详细执行信息,比如下游节点等待数据时间、扫描节点打开 HDFS 文件所耗时间等。
在 Timeline 中可以了解到查询时间消耗,如左上图的时间消耗主要是加载元数据信息,其中 "loaded-tables=1/1" 表示查询里涉及 1 个表,本次加载了 1 个表;“load-requests=28”表示总共向 Catalogd 发送了 28 次 PrioritizeLoad 类型的元数据请求;"catalog-updates=549" 表示总共等了 549 轮的 Catalog 广播更新;“storage-load-time=510879ms”表示加载文件元数据花了 510879ms。整个元数据加载的等待时间是 9m15s。
又如上图的右下子图,查询的时间消耗主要是排队等待上。
Impala 查询的 Summary 总结了查询各个 Fragment 和 Node 的耗时等状况,包括并发执行的节点数、平均耗时和最大耗时、预估和实际处理行数、预估和实际使用内存等。
另外我们会进行 SQL 注解,以及结构化保存。通过注解的方式记录了相当多的信息内容。其中包括物化视图命中状态、报表状态,以及命中物化视图对应的表的改写代价等等。
3. 挖掘历史查询规律
如上图,透过 SQL 注解以及其他历史查询信息,我们可以得知集群状态,了解到具体的任务排队情况,预测内存使用情况。
通过历史查询信息,我们还可以得知查询次数以及查询性能随时间变化的一个规律,得知集群繁忙状态。
通过在成千上万的 SQL 查询中,分析各类不同 SQL 中的差异,归纳总结出 SQL 模版,用以提升 Impala 查询的内存预估效率,并为其他决策提供支持。同时,在如此多的查询信息中,很容易得知热点表/分区的信息。
4. HBO 优化实践
Impala 有较为完善的本地缓存体系,包括元数据缓存和 HDFS 文件缓存。但也因为有缓存,所以导致了一些缓存过旧问题,因此出现查询时的元数据错误。数据缓存也同样存在问题,包括重启失效,不命中代价较高等。
基于如上的一些问题,我们针对本地缓存体系进行了优化。
在元数据缓存模块,所做优化包括过滤无效表、合并同类 DDL、暴露同步进程和通过SQL 注解手动指定查询涉及的表信息,以及通过动态白名单驱动表元数据异步加载。
在 DataCache 增强方案上,对于 Parquet 等文件格式,支持独立配置 Footer Cache,因为 HDFS 在读文件时先会读取 Parquet 文件的 Footer Block,之后解析这个 Block 的信息,才可以进一步做过滤等其他操作,再真正去读数据。我们会优先将 Footer 块缓存,另外解决了 Cache Fill 性能退化问题。
我们还解决了 DataCache 持久化问题,以保证重新启动后依旧留存有之前的缓存数据信息。避免了 Impala 进程重启缓存丢失的情况。
5. 基于 HBO 的多表物化视图
物化视图目前主要用于 BI 报表场景,由于 SQL 是批量下发的,若部分 SQL 执行时间长,将会对集群造成不小的压力。BI 报表对实时性能要求较高,其查询规律性强、重复率高、T+1 类型较多,适合用物化视图进行加速。
物化视图的实现方案,目前主要包括两方面,其一是生命周期的管理,这部分是我们纯自研,以独立服务形式部署,元数据存储在 MySQL 。通过数据产出消息、DDL 变更日志和文件驱动物化视图表数据更新;其二是 SQL 透明改写,该部分内容目前是以 Calcite 物化视图为基础,进行二次开发增强。因为在调研的过程中,我们发现 Calcite 提供了一个较好的框架,提供了 SQL 自动改写的能力,该能力支持多表 Join。
下面稍微展开讲下 Impala 物化视图自动改写能力。它基于一篇 SQL Server 的SIGMOD 论文来实现。从实现的角度来讲:Impala SQL 会先转变成 Calcite AST 语法树,再到 Rewrite 阶段进行重写,之后又转回为 Impala SQL,再由 Impala 继续处理。在集成方面,我们通过一个 Jar包,放入 Coordinator 的 EF 端来实现。在此处更类似一个插件,对于以后版本的升级迭代都更加方便。
由于 Calcite 开源组件本身还存在不少的缺陷,包括 SQL 匹配以及改写效率上的问题,在生产环境中,我们对此进行了进一步的优化,包括添加了 Outer Join、Group By、Limit 等算子和各种 UDF 的支持。
HBO 在物化视图的使用主要是通过分析有数 BI 报表的历史查询记录,确认要获取优化的对象并创建物化视图。
物化视图的创建,又以不同的颗粒区分,比如:慢图表、慢报告、慢模型。创建物化视图一定要考虑投入产出比,如何用最小的资源消耗获取最大的产出,是很重要的问题。
对于一个创建好的物化视图,如何评估这个物化视图的效果?我们通过 Coordinator层面提供了一些 Metrics,它会记录每个物化视图的命中情况,命中之后改写性能消耗,还有物化视图表自身有多少的数据量、占用了多少空间等信息。
通过BI产品的报表数据医生也可以看到 HBO 优化的效果。
6. 基于 HBO 的内存预估优化
Impala 会为查询预分配内存,因此,预分配的内存决定了集群内存的使用效率,若是预估值过大,Impala 会一直占用这部分资源到 SQL 查询结束,这会平白浪费不少资源。对于这部分,我们目前通过 SQL 模板进行优化,从结果上看,我们尽可能地更正了预估的数值,提高了资源利用率。
7. 虚拟数仓与资源动态调配
所谓虚拟数仓就是一个集群中,分了多个组,每个组完成不同的业务,从而进行有效的负载隔离。它拥有两种方式,第一:基于zk的命名空间,Impala 上不同的 Coordinator 注册到不同的 ZK 地址,通过不同zk地址拿到不同 Coordinator 的连接,就会到达不同的虚拟数仓上。
另外一种为同一个 ZK 地址,所有查询都会到达同一组 Coordinator,可以通过 Set Request Group 的方式来将你的查询路由到某个虚拟分组中去,这种方式类似 Snowflake。
虚拟数仓涉及到资源的高效使用和负载均衡, 我们的解决方式是混合型虚拟数仓 ,也就是节点可以在不同的虚拟数仓中,又可以分为两种,一是 Executor 在不同虚拟数仓中,另一种是 Coordinator 注册到 Zookeeper 不同的 Znode 上。
04 未来发展计划
1. Impala 4.1 版本
- 已完成自研特性合并
- 添加 Hive 2.x 版本支持
- 推进上线中
2. 物化视图
- 支持更多 SQL 语法和算子
- 提升物化视图创建的自动化程度
- 与有数 BI 产品进一步融合
3. Impala 内核优化
- 进一步提升 HBO 内存估算能力
- 支持更多场景的查询透明重试
- 支持向量化执行模式
4. 集群管理和运维
- 支持通过 K8S 进行 Impala 集群部署
- 资源动态调度和负载均衡
- 集群健康状态诊断系统
|分享嘉宾|
温正湖
网易数帆 数仓技术负责人
2010年浙大硕士毕业,10+年数据库和存储开发经验。2013年入职网易数据库团队,一直从事关系型数据库和分析型数仓相关工作,专注于数据库领域技术创新、研发和应用。