网易Impala集群优化和高可用负载均衡配置和虚拟数仓

网易Impala集群优化和高可用负载均衡配置和虚拟数仓

  • ① 本文阅读了多篇文章整理润色而成,主要旨在解决impala分析型数仓在生产环境遇到的各种技术瓶颈。如何优化等一些列问题着手。
  • ② 文章原作者是网易资深大数据开发工程师,拜读他的文章后深受启发。
  • ③ 关于impala优化从四大痛点出发,依次给出分析和解决方案。
  • ④ impala集群的内存是否设置的越大越好?并发数是否越大越好?
  • ⑤ impala2.x的执行组和后来的节点组,资源池配置,与虚拟数仓什么关系?
  • ⑥ 什么是虚拟数仓?
  • ⑦ 文章底部有原文链接。

▌痛点分析

Impala简介

在开始正式议题前,首先简单介绍一下Impala。Impala是一个存算分离的MPP架构数据查询分析引擎,其特点是有比较高的查询性能。同时,Impala 的历史较为悠久,在生产环境应用广泛,功能特性比较符合企业级的应用场景,比如丰富完善的鉴权、认证和脱敏等能力。

在这里插入图片描述

网易NDH主要将Impala用在BI报表、数据抽取、自助分析和跑批任务这四类场景,下表对这四种场景从SQL模式、查询时长、资源消耗、查询并发以及元数据变更等特点进行了总结:
在这里插入图片描述

BI报表:特点是模式比较固定,并发有时会比较高,对性能的要求也很高,因为基本都是分析师或者领导老板在看,他们对性能的忍受程度是很有限的。这些SQL的资源消耗一般是比较少的。
数据抽取:该类型的场景一般是独立的业务组件,通过SQL的方式进行数据抽取,也有可能是集成在BI等的产品或工具里面。它的特点也是模式会比较固定,并发是可控的。相对来说资源的消耗会比较大,耗时也会更长一些。
自助分析:特点是非常灵活,资源消耗可能很少,也可能很大,时长也可短可长。但是基本上会集中在上班时间。
跑批任务:主要用来做数据加工,比如基于明细层做跑批,加工成更高的汇总层,以及集市层的一些数仓分层。它的特点跟数据抽取有一些类似,但是也有一些独特的地方,它会触发表和文件的元数据变更。在生产环境实践的时候发现,这个是Impala使用的一大痛点,可能导致SQL阻塞等问题。

Impala痛点分析

本章节将介绍我们在混合负载、资源管理、元数据异常以及查询性能方面遇到的痛点。

在这里插入图片描述

痛点一:混合负载

混合负载是我们经常遇到的场景,比如BI报表对性能和成功率要求都很高,但是在混合场景下,成功率往往难以保证,原因主要有两个:

一是BI报表类产品本身的原因,产品侧对不同的BI的查询类型没有进行资源的隔离,比如BI产品可能既支持报表类的应用,也支持数据抽取,抽取就是把一个数据源的数据抽取到另外一个数据源,类似于数据加工。

这两种不同类型的查询,如果共用同一个资源队列,就会导致资源竞争比较严重,出现排队等问题。

在这里插入图片描述
​ 第二个原因是因为Impala或其他的一些查询引擎,往往会基于资源队列进行隔离,但是本身隔离是不够彻底的。**比如队列里面的查询只支持FIFO规则先进先服务。**对于Impala来说,资源队列没办法对CPU资源进行隔离,另外,如果存在多个队列,所有队列加起来配置的总资源可能是超过物理内存的,这个时候就会出现一些问题,比如并发太高,或者内存不足时都有可能导致查询排队等待,对性能有比较大的影响,甚至可能导致查询出错。

在这里插入图片描述

痛点二:资源管理粗放

资源管理粗放是一个共性的问题,不仅仅是Impala这样,其他数据库或查询引擎,包括有些关系数据库也存在资源预估不准的问题。我们在生产环境遇到的问题有两类:

其中一类就是内存的预估值远远大于实际查询的使用,为查询预留了太多内存,导致虽然有很多的内存是可以使用的,但却没办法真正地用起来,所以说效率比较低。这就进一步导致因为没有实际可用的内存,或者没办法分配出来的内存,引起后续进来的查询只能排队等待资源。这里举了一个例子,预估值和实际的使用差了将近20倍。

在这里插入图片描述

第二类是内存的预估值过小了,查询实际需要的内存超过预估值,会导致执行过程中报出内存超阈值(mem limit)错误。

在这里插入图片描述

痛点三:元数据异常

元数据异常主要表现在两个方面:

第一个是元数据缓存过旧问题,之前一直认为它是Impala特有的一类问题,因为其它SQL引擎多为存算一体,自己带存储并直接跑ETL任务,元数据本来就是引擎内部,因此不存在元数据缓存的问题。但是**在存算分离这种架构下,可能是通过Spark或者Hive来跑批的,用Impala做查询,如果跑批过程增加了一个分区,Impala并不知道分区增加了,就会导致Impala的元数据缓存过旧。**现在我们已经进入数据湖时代,在数据湖里存算分离本来就是一个公共的属性,在这种情况下如何解决缓存的有效性问题,比如缓存什么时候更新以及怎么失效等等是大部分查询引擎需要共同面对的问题。

在这里插入图片描述

第二类元数据异常是元数据同步的阻塞,是Impala自己特有的一类问题。

典型的现象就是coordinator webui上有大量查询处于in flight状态,或者基本上所有的查询都处于created的状态。原因是在跑批任务中对表进行了变更,比如增加了分区需要更新元数据,那么在catalog上就需要对表加写锁。 **Impala集群内部的元数据同步的机制是从catalog批量收集一批表的元数据,通过statestore广播到coordinator。**catalog在收集元数据的时候需要为每个表加一个读锁,如果这时候某一个表有跑批的任务,或者因为其他原因加了写锁,那么收集线程加读锁的逻辑就会被阻塞住,这就导致对应的 coordinator上的这些查询得不到执行(处于created状态)。

在这里插入图片描述

痛点四:查询性能不足

总体来说,Impala是一款较全面均衡的查询引擎,绝大部分场景下,性能可以满足业务要求。但相比目前业界最领先的水平,查询性能还有所不足,这里也分了两类:

第一类是与Impala自身相关,不受部署环境等其他因素影响。由于Impala目前还缺乏向量化执行的能力,在基于CBO的SQL优化,比如Join次序的调整能力上也有不足,这会导致大表扫描叠加多表Join类的复杂查询性能相对业界领先水平还较差。

补充知识:三种常见的数据库优化机制:

CBO: Cost-Based Optimization也即 “基于代价的优化器”,该优化器通过根据优化规则对关系表达式进行转换,生成多个执行计划,然后CBO会通过根据统计信息(Statistics)和代价模型(Cost Model)计算各种可能 “执行计划” 的 “代价”,即COST,从中选用COST最低的执行方案,作为实际运行方案。

RBO: Rule-Based Optimization也即 “基于规则的优化器”,该优化器按照硬编码在数据库中的一系列规则来决定SQL的执行计划。

以Oracle数据库为例,RBO根据Oracle指定的优先顺序规则,对指定的表进行执行计划的选择。比如在规则中:索引的优先级大于全表扫描。

HBO:History-Based Optimization基于历史查询的内存估算优化(HBO)
在这里插入图片描述

第二类性能问题是受外界因素的影响,与部署方式有关。比如目前我们大部分的线上部署方式都是存算分离的,也就是Impala的节点跟HDFS节点不在同一台机器上,读数据以及打开文件都是跨网络的,就会受到网络性能的影响。另外,使用公共的HDFS存储,可能导致大家共用存储的IO资源出现竞争。

这里举了两个例子:

第一个是由NameNode的性能波动导致的,使得Impala打开文件进行数据扫描时,性能比较差。
在这里插入图片描述

第二个是DataNode的性能随着HDFS的负载变化而有很大不同,比如DataNode存在IO热点时。如下图所示,在HDFS使用高峰期执行Impala查询,SCAN HDFS阶段耗时最长要2分钟。而低峰时执行同一查询,SCAN HDFS只要不到5秒钟,差异非常大。

在这里插入图片描述

痛点汇总:

▌痛点解决,高性能SQL引擎的建设方案

1. 资源与负载管理

(1)高可用和负载均衡

​ Apache Impala虽然一个集群能够部署多coordinator,但关于多个coordinator怎么高可用访问并没有提供一个官方或者标准的解决方案,官方只是建议部署HA Proxy等来进行高可用和负载均衡。我们在这方面做的优化是参考Hive的高可用方式,实现了基于zookeeper(ZK)的coordinator的高可用和Impala查询的负载均衡。

在这里插入图片描述

​ **具体做法就是把各个coordinator的地址注册到同一个ZK的Znode上,然后客户端可以通过Hive JDBC来访问Impala集群,它的访问模式是会先访问ZK里面的指定目录,随机取某一个注册的coordinator地址来建立连接,这样就达到了高可用的目的。**某一个coordinator挂掉对于整体Impala 的服务没有多少影响。同时,由于是从多个coordinator随机获取一个,也达到了负载均衡的效果。

(2)虚拟数仓

​ **基于ZK的高可用和负载均衡的特性,我们进一步做了另外一个新的特性,就是虚拟数仓。**虚拟数仓的说法是从Snowflake来的,但我们做的这个特性其实是早于Snowflake的,在Impala 2.x版本就已具备,之前叫做Impalad分组功能。

在这里插入图片描述

Impalad分组把一个Impala集群分成很多个组,不同组的Impalad相互之间是看不到的,每个组只能看到自己组内部的Impalad,这样就达到物理资源的隔离。每个组的coordinator可以选择注册到同一个或者不同的Znode上,如果是不同的组在不同的ZK地址上就可以承接不同类型的查询服务。比如有一个组是跑批的,有一个组可能是做BI查询的,有些是做数据抽取的等等。

在这里插入图片描述

相比于多个集群,虚拟数仓本质上还是一个集群,共用同一份元数据,同一个catalogd和statestored,所以会更轻量化。在运维层面更加灵活和简单,比如元数据同步不需要给每个集群都配一个。
​ 虚拟数仓有比较好的扩展性,如果业务发展得比较好,负载以及并发一直在提高,以至于超过了一个虚拟数仓可以承载的水平,我们可以基于虚拟数仓进行扩展,添加一个同规格的Impalad分组,其coordinator注册到同一个 ZK地址上,依托Hive JDBC随机选择coordinator的特点,这样就达到了服务能力的水平扩展的效果。
另外,我们也做了查询(业务负载)跨虚拟数仓调度的能力,目的也是尽可能充分地利用有限的计算资源,下面举一个虚拟数仓的使用案例进行说明。

在这里插入图片描述

​ 假设有两个虚拟数仓,分别用来执行跑批任务和BI报表查询,BI报表一般是在上班时间查询的人会比较多,跑批一般是在晚上或者凌晨,这两类任务高峰期是错开的。这就意味着有一个虚拟数仓处于高峰期的时候,另外一个虚拟数仓处于低峰期。其实完全可以把处于查询高峰期的虚拟数仓上的部分查询路由到另外一个很空的虚拟数仓上,这样就可以充分利用计算资源。

(3)队列管理增强

​ 我们在Impala原生的队列管理上也做了一些增强,主要提供了两种新的能力,分别是基于优先级的能力,以及跨队列的动态路由的能力。
优先级又分成两种: 第一种是队列里的查询是有优先级的,支持为不同类型查询配置执行优先级,保障重要的查询先被执行,如果资源出现瓶颈,高优先级的查询可以抢先排到队列的前面,更快地得到执行.

还有一个优先级是队列的优先级,一个Impala分组或者集群里面有很多的队列,可以为这些队列划分不同的优先级,在负载非常高的时候,先保证优先级最高的队列里面的查询能够先得到执行,其他队列会限制执行时间。
跨队列的路由能力,支持将特定类型的查询路由到其它资源队列以便单独进行配额的管理。

比如可以将不同用户下发的查询放到不同的资源队列,因为业务层面不一定对Impala非常了解,可能不会使用队列,所有任务都下发到default队列,这个功能就可以在Impala集群层面来进行查询的分发,放到不同的队列里面进行配额的控制。

在这里插入图片描述

(4)基于历史查询提升内存利用率

​ 基于历史的查询优化是NDH Impala基于管理服务器做的一个新的特性,我们叫作HBO。它的原理是利用前面提到的管理服务器持久化保存所有的历史查询信息,这个信息包括SQL语句的内容、任务执行预估内存以及实际消耗的内存等。我们新增了一个HBO模块,它会提取这些SQL的模板,以及涉及到的表、分区字段和分区个数等信息,进行加工保存在HBO元数据表里面。

coordinator缓存HBO元数据表并周期性更新,在执行查询的时候,先提取查询SQL模板,判断它是不是跟HBO元数据缓存里的模板匹配,如果匹配就意味着命中了HBO,那就使用已经执行过的同类的SQL的内存的实际使用值,来作为当前查询的一个预估值。

在这里插入图片描述

目前 HBO 能力在很多的业务集群已经使用了,效果非常明显。下面例子是前面提到的预估值和实际使用值差了20倍的案例,启用了HBO以后,就变成只有实际使用值的2倍,所以资源使用效率提高得非常明显,同时因为内存资源被充分地利用起来,从而查询排队的概率就变得比较小,排队的时间少了,平均的查询性能也就进一步得到了提升。

在这里插入图片描述

2. 元数据管理增强

(1)元数据同步

元数据管理层面的优化第一个方面是元数据缓存,解决Impala集群跟外部组件的元数据同步问题,比如在Spark和Hive上做表数据加工时,需要及时把元数据变更同步过来。

在这里插入图片描述

**开源社区Impala3.x版本以后支持了元数据同步,**也就是上图列出来的第三种方式,我们基于社区版的实现做了一些优化,解决了一些BUG并做了增强。这种元数据同步的方式对于原来CDH的用户迁到NDH上是比较有用的,因为涉及到集群迁移NDH的Impala底层依赖的Hive以及HDFS还是CDH的版本,这种情况只能是用社区版的实现。
另外两种元数据同步都是网易数帆自研的,分别是基于NDH Hive MetaStore的DDL变更日志和基于EasyData数据开发平台离线任务的表数据变更消息订阅。

(2)分区元数据裁剪

元数据管理第二类增强是元数据在Impala集群内部缓存或广播时的增强。
**首先做了分区元数据裁剪,解决元数据的缓存空间过大的问题。**如果Impala集群有非常多的表,表有非常多的分区,它需要缓存的元数据会非常大。虽然Apache Impala做了很多优化,但有进一步优化的需求和空间。
Impala 4.x版本的local catalog模式是一个非常好的特性,对减少 coordinator侧的元数据缓存的大小非常有帮助,因为local的意思就是 coordinator是按需而不是全量从catalog获取元数据信息。但是local catalog模式仅针对coordinator,没有解决catalog的元数据缓存空间的问题。

在这里插入图片描述

如果catalog中存在有非常多的分区或文件的表,可能会导致需要缓存的元数据很多,所需缓存空间越大,意味着catalogd需配置的JVM内存就越大,但这很难能够精确地量化出来,如果配得小可能就会导致严重的GC问题,进而导致coordinator的查询出现异常,比如查询卡住等等。
我们做的优化就是减少catalog的元数据缓存量,着眼点是减少分区数非常多的表的元数据缓存空间,只缓存Impala经常会查到的那些分区的元数据,不常查的那些分区的元数据就不缓存了,需要时再从MetaStore和 NameNode上加载。例如有张包含5年的每天分区的表,一般情况下只会查询最近一个月的数据,比较旧的分区基本不会查到,那么catalog中就只需要缓存最近一个月的元数据。

(3)元数据无锁广播

元数据在内部进行通信时,比如从catalog到coordinator这个过程中,前面提到的一个痛点就是阻塞,coordinator侧会出现很多处于created状态的查询,因为Impala的元数据收集机制是一批一批的多个表一起收集,如果有一个表加了写锁就会被阻塞。

Apache Impala在这一块做了很多优化,也在 4.x版本提供了表锁等待超时等新的能力。对于加了锁的这些表,元数据收集线程就不是一直等待,而是会等待超时。**如果超时,对应表的元数据就跳过了,只收集其它没有锁的表。这样大大提高了元数据收集和广播的效率。**但是虽然可以把等待的时长调小,但有些场景下,还是需要等待比较长的时间,所以对coordinator上的查询性能还是有不小的影响。

在这里插入图片描述

我们做的优化是会根据表更新、添加或删除分区等这些数据更新操作的频率以及查询频率等,来决定要不要在元数据收集逻辑上把表锁去掉。 当然这样做意味着可能导致这个表的元数据更新会被遗漏,coordinator得不到该表的最新的元数据。我们做的补偿是会把coordinator上这张表的元数据缓存失效掉来确保正确性没有问题。通过这种方式,在一些场景下可以明显提升coordinator上的SQL性能。

3. 查询性能优化

(1)Impala新版本特性优化

第一个优化是充分发挥Impala新版本的性能

我们从Impala 3.4版本升级到 4.1以后,目前主要用了两个与性能相关的新特性:

  • 第一个是Multi-thread Execution(MT_DOP),即进程内多线程执行查询;
  • **第二个是异步的动态代码生成(codegen)。**走同步codegen的查询在执行之前,需要等到codegen完成后才能执行,异步方式则会先基于非codegen函数的版本开始执行,在codegen完成时通过函数指针的切换再使用最新的codegen函数版本来加速。

在这里插入图片描述

这两个特性我们在线上都开启了,在开启的过程中发现MT_DOP特性还有不够完善的地方,比如我们可以在查询低峰期或者是集群CPU 资源比较空的时候设置比较高的并发度,但是如果集群的负载上来了还设置这么高的查询并发可能就会导致整个机器的CPU负载过高,反而对性能是有害的。

所以我们引入了一个基于CPU负载的MT_DOP自适应的能力,它会监测Impalad当前CPU负载情况,如果CPU的负载超过某个阈值,就会对应地把 MT_DOP值调小,如果负载处于比较低的水平,查询就可以设置更高的线程并发度,利用更多的计算资源,让它更快地执行完,确保CPU资源被充分利用但又不至于过载。

在这里插入图片描述

性能优化的验证举线上某集群为例,该集群去年9月底上线Impala 4.x版本,到12月份完成一轮性能优化,刚开始查询的性能平均是4秒多,使用前面的两个特性优化后,平均的查询性能降到了2秒以下。1秒、3秒和5秒以下查询所占的百分比都提高了很多。

在这里插入图片描述

(2)多表Join的物化视图

**第二个性能优化是通过预计算进行性能加速。**我们开发了多表Join的物化视图,该特性适用于那些SQL模式比较固定,出现频率比较高的场景。在实现上分为两个部分:

第一个是物化视图的创建、数据更新、删除等。我们自研了一个独立服务,通过前面提到的多种元数据同步的方式来驱动物化视图的数据的更新。

在这里插入图片描述

**第二部分是SQL的透明改写。**透明改写做到了Impala的coordinator里面,改写模块基于Apache Calcite物化视图的能力实现,并在此基础上做了很多的增强,比如原来Calcite仅支持inner join,不支持outer join等其他Join类型、不支持group by和limit等算子、不支持Impala特有的UDF等,这些都做了支持。下图是我们去年在业务场景落地时截取的一个效果图,命中物化视图的效果非常明显。

在这里插入图片描述

(3)DataCache优化

**第三个性能优化点是DataCache。**DataCache在Impala 3.x版本就已经支持,到了4.x版本得到进一步完善。我们在这个基础上做了一些增强,重点解决了缓存不命中的问题。开启缓存后,原始的数据读取流程是查询时如果缓存不命中,需要从HDFS里面把数据读出来,先放到缓存中,然后再返回给查询。我们做的优化是数据读出来以后直接返回给查询,再异步填充到缓存里面,这样可以减少对查询性能的影响。

在这里插入图片描述

除此之外,我们还提供了缓存白名单功能,可以选择只缓存某些表。对 Parquet、ORC这种文件格式提供了我们提供footer的缓存。还通过把缓存元数据持久化功能解决了DataCache在Impalad重启后数据缓存失效的问题。这些优化工作我们正在贡献给社区,通过DataCache能够解决存算分离模式下存储层性能波动导致的影响,优化后的效果如下图。

在这里插入图片描述

(4)查询成功率保障

查询成功率保障也跟Impala 4.x版本的一个新特性有关系,新版本提供了查询透明重试的能力,但它目前只是在Impalad宕机的时候才会进行查询重试,即下图提到的第二点,就是executor的节点宕机等场景。我们做的增强有2点:一是如果因为元数据缓存过旧导致查询错误,会选择把表的元数据先刷新再执行。

在这里插入图片描述

二是对于内存预估不准的问题,预估值小于查询实际需使用的内存值时会导致查询失败,我们会把预估值调高后再做重试。关于预估内存方面还有其它一些优化,比如直接放宽mem limit,改为引入一个新的参数,用来对查询进行比较宽泛的最大内存消耗值限制。

▌使用案例

本节通过一个客户的业务案例来说明优化效果,这个业务的BI报表本来是在Oracle上,后来迁移到我们的Impala上。

在这里插入图片描述

迁移过来的时候我们所做的优化大部分都没有启用,性能表现远远不符合预期。

​ 因为前述的内存预估不准问题,导致内存资源浪费非常严重,并发高了以后排队问题很严重,比如预估值会超过几十G,但其实只消耗几个G。

还有个痛点是并发查询性能下降明显,并发度高了以后甚至会造成所有查询都卡死了。

上面的各种问题导致了查询成功率低,用户满意度比较差。举下面的例子为例,没有并发的时候45秒之内返回,本身已经比较慢了,但如果并发上来以后,性能线性下降,到10个并发时,查询耗时已将近200秒。

在这里插入图片描述

我们优化的过程如下:

​ 首先是规范了集群的配置和部署。比如在执行过程中有详细的日志输出、在WebUI上保留更多已经执行完的查询(管理服务器需从coordinator的WebUI拉取历史查询进行持久化)。另外是coordinator负载均衡,客户所使用的第三方BI产品没有承诺支持Hive JDBC,所以最开始业务层直接连到一个固定的coordinator上,由于前述原因,导致整个集群同时执行不了几个查询。我们通过调研,确认BI产品本身是支持Hive JDBC ,且在其他客户上已有使用经验,故推动客户将Impala集群访问改造成基于ZK的模式。

​ 第二个优化是启用管理服务器来收集持久化这些历史查询信息,方便从中挑选出性能比较差的来分析性能差的原因。在此过程中,我们发现了比较多的可优化点,比如查询因为有排序等操作,存在比较严重的数据溢出,后来还发现在Impalad之间做数据交换/exchange环节存在严重的网络拥塞。通过排查发现数据溢出避免不了,因为排序的时候确实数据集比较大,通过把数据溢出盘换成更高性能的SSD盘进行性能优化。网络拥塞的问题是因为这个集群里面有些节点是万兆网卡,有些节点因为错配的原因是千兆的网卡,识别出后就可以针对性优化,优化后性能提升非常明显。

在这里插入图片描述

​ 第三个优化就是启用前面提到的虚拟数仓特性,业务场景可以区分出普通报表和复杂报表,复杂报表倾向于做数据抽取,有很大的结果集,会把这个结果集导出做进一步分析。我们通过虚拟数仓把这两类报表隔离开,避免相互干扰。

最后做的事情也是在这个基础上通过启用HBO尽可能地提高资源利用率,下面是我们启用HBO以后的效果,没有启用之前,预估值是几十G。启用以后,预估值跟实际的使用值相差无几。

在这里插入图片描述

下图是普通报表和复杂报表在优化前后的整体性能对比,可以看到有着明显的提升。

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值