导读:
本文主要介绍网易数帆 NDH 在 Impala 上实现的虚拟数仓特性,包括资源分组、水平扩展、混合分组和分时复用等功能,可以灵活配置集群资源、均衡节点负载、提高查询并发,并充分利用节点资源。
接着上一篇。对于高性能分析型数仓,除了需要有优秀的执行引擎能够让查询尽快完成外,还需避免因为查询间的相互干扰导致查询性能下降的问题,比如对计算和 IO 资源的竞争等。上节提到 Impala 可以通过资源池来进行计算资源的管理。但在使用时发现光有资源池还不够,仍然会出现不同的资源池竞争同一个计算节点上内存资源等问题。
1 基本概念
“虚拟数仓” 来源于 Snowflake 的 “virtual warehouse”,简称 VW。虚拟数仓能够按需进行水平和垂直扩缩容,是一种高效的资源调度方法,是存算分离设计架构下,计算资源弹性伸缩非常好的验证案例。如下图所示,该 Snowflake 集群有两个虚拟数仓,分别服务于 BI 和 ETL 用户。其中 BI 虚拟数仓为了应对报表查询的高低峰,采用了单元化的水平扩缩容模式,ETL 主要关注计算能力,采用了改变虚拟数仓规格的模式。
NDH 的 Impala 组件也具备类似的能力,在开始之前,先结合 Impala 的实际来介绍两个基本概念,首先是社区版 Impala 已有的 executor group(执行组)。然后是为支持虚拟数仓而引入的 node group(节点组)概念。
Executor group
下图是 CDP 文档中关于 Impala 执行组的示意图,执行组是 Impala 进行弹性伸缩的基本单位,用户可以配置执行组规格 (XSMALL, SMALL, MEDIUM, or LARGE)。若启用自动伸缩,则 CDP 每次会按指定的规格扩展或缩小 Impala 的 executor 节点个数。
执行组为 Impala 集群提供了水平扩缩容的能力。但与 Snowflake 所述的虚拟数仓还是有不小的区别,从目前的介绍看,执行组是对用户透明的概念,用户无法通过执行组将 Impala 集群划分为不同用途的计算单元,如前述的用于 BI 和 ETL。因此,NDH Impala 引入了 node group(节点组)的概念。
Node group
NDH Impala 集群的 impalad 节点可以被划分成多个独立分组,我们称之为节点组。节点组可以仅有 executor 组成,也可以有 coordinator 节点。
上图 Impala 集群包含 3 个节点组,每个节点组的 impalad 中必须至少有一个 executor 节点。此外还有 2 个 coordinator 节点独立于节点组之外。独立的 coordinator 节点可以将请求路由到任一节点组中的 executor,节点组中的 coordinator 只能将请求分发给本分组内的 executor 节点执行。根据查询路由规则的差异,有两种虚拟数仓实现方式。
2 实现方式
NDH Impala 支持两个虚拟数仓实现,分别是基于 zookeeper 地址的静态配置方案和基于会话(session)参数的动态配置方案,下面分别展开介绍。
2.1 静态配置
该方案将不同节点组的 coordinator 节点注册到不同的 zookeeper 地址上,Hive JDBC 客户端连接不同的 zookeeper 地址即可获取到不同业务组的 coordinator,从而进行连接并下发 SQL 请求。此种方式中每个节点组都会拥有自己独有的一到多个 coordinator 节点,负责将 SQL 生成的执行计划下发给组内的 executor 节点执行。
上图所示集群有 3 个虚拟数仓:group 1,group 2 和 group 3。它们共用相同的 statestored 和 catalogd,共用同一份数仓元数据。虚拟数仓间的 impalad 资源是物理隔离的,某个虚拟数仓的 coordinator 节点只会将查询下发到组内的 executor 节点。在生产环境中,可通过配置多个虚拟数仓来接收不同类型业务的查询请求,以便不同业务的查询在计算资源的使用上互相隔离,互不影响,图中 group 1 用于进行 ad-hoc 查询,group 2 用于有数 BI 报表,group 3 用于有数 BI 自助取数。相比多集群方式,多虚拟数仓的方式所需要资源更少,配置更灵活。
2.2 动态路由
本方案在会话连接中增加一个 query option 参数 request_group,通过 set request_group=xxx 语句,coordinator 会自动将查询路由到指定分组上执行。request_group 默认为 default,对应 group_name 的默认值也为 default。换言之,若不指定 request_group,那么查询会下发到默认的 default 分组执行。
在本方案中 coordinator 节点是公共的,仅对 executor 节点进行分组,在实现上更类似 Snowflake 的虚拟数仓。如下图所示,有 2 个公共的 coordinator,3 个分组,由于不存在 default 分组,可将默认分组配置为 grp1。可以通过参数动态配置,相比基于 zookeeper 的方案更加灵活,用户能够根据需要自由地将查询在不同的虚拟数仓上切换。
上述两种方案均已实现,由于 NDH 的生产环境一般通过 Hive JDBC 连接 zookeeper 来访问 Impala,前者的使用方法兼容性更好,目前线上主要使用以该方式部署虚拟数仓。本小节接下来介绍的虚拟数仓进阶特性也主要围绕前者展开。
3 主要特性
3.1 水平扩展
若虚拟数仓的单个节点组资源和并发数已经达到瓶颈,单纯在组内增加节点无法有效提升查询并发数,此时可以新增一个规格相同或相近的节点组加入该虚拟数仓中,需将新节点组中 coordinator 的 zookeeper 地址配置成与原节点组相同。借助 Hive JDBC 在选择 zookeeper 下 coordinator 地址时的随机性特点,可将查询负载均衡到新旧节点组上。这种方式可以接近线性地提升集群的查询并发数。
上图所示 Impala 集群有 2 个虚拟数仓,对应的节点组分别为 group1 和 group3,承接的业务分别是业务的有数 BI 报表和 ABTest 场景。假设 group1 为原分组,有 3 个 impalad 节点(1 个 coordinator,2 个 executor)。新增分组 group2,也是 3 个 impalad 节点,使用与 group1 相同的配置,即可起到水平扩展的效果。
3.2 透明伸缩
NDH Impala 可根据各虚拟数仓的负载情况,在线增加或减少虚拟数仓节点组中的 impalad 节点数,从而实现分组间的资源动态伸缩。通过 Impala 提供的 graceful shutdown 方式下线节点组中 impalad 进程时,会先禁止新的查询请求发送到该 impalad 节点上,并等待其上正在执行的查询片段(fragment)完成后再关闭。因此不会导致其上正在执行的查询异常终止,做到对用户无感。在生产环境中,配置了多个虚拟数仓的 NDH Impala 集群,可通过分析历史查询规律并结合分组中 impalad 节点的系统负载情况,在虚拟数仓间动态增减节点数,以求更充分得利用各节点资源。
举网易云音乐为例,有数 BI 自助取数(easyfetch)的查询一般发生在工作时间,有数 BI 报表需要在用户上班前进行大量报表结果预加载操作(提前下发报表查询 SQL 并缓存查询结果从而提升报表查看体验)。我们可将 easyfetch 和 BI 报表两种场景配置为同一个 NDH Impala 集群的两个虚拟数仓,在上班前,将 easyfetch 虚拟数仓的大部分 impalad 节点挪到 BI 报表虚拟数仓上,这样可以大大提高报表的预加载效率。
当然,透明伸缩不仅仅适用在虚拟数仓之间。对于云上环境,通过 k8s 或类似调度机制,在负载高峰时可以便捷地申请容器或虚拟机资源,快速补充到线上。待高峰过后,再将所增加的资源释放给云厂商。
4 进阶功能
相比 Impala 资源队列,虚拟数仓的节点组中 coordinator 节点绝对不会使用到其他组的计算资源(executor),资源隔离更加彻底,使得不同业务模块的查询性能不会相互影响。但不同虚拟数仓所属的业务会存在负载差异,可能导致资源利用不充分。为了提高空闲节点组的资源利用率,对虚拟数仓特性做了进一步增强,引入混合分组、分时复用等功能。
4.1 混合分组
混合分组就是让一个 executor 节点同时在 2 个或以上的节点组中,如下图所示。左子图为普通模式,假设 NDH Impala 集群分为有数 BI 报表和 Ad-Hoc 查询 2 个虚拟数仓,Ad-Hoc 查询有明显的时间性,查询集中在工作时间,且查询的并发度较低。通过混合分组,可将虚拟数仓部署方式改造为右子图的模式。
图中,n1n2 为 group1 节点组 coordinator 节点,其会注册到 zookeeper 路径 youdata 上,Hive JDBC 客户端从该路径获取任意 coordinator 节点向其提交查询,coordinator 将查询进行解析,优化并指定分布式执行计划,最终下发给 n3n7 执行。n6n7 同时还是 group4 的 executor 节点,group4 的 coordinator 为 n8n9,其会接收从 zookeeper 路径 Ad-Hoc 进入的查询,指定分布式执行计划,并会发送到 n6~n8 上。
4.2 分时复用
分时复用是另一个能够提高资源利用率的进阶功能。通过在特定的时间段自动配置集群的分组资源,缓解某些高负载分组的查询压力,提升用户体验。
在实现上,支持将同一个 coordinator 注册到多个 zookeeper 地址下,且可以配置注册到每个地址的有效时间,如上图所示,可以每天晚上八点到早上八点将 Ad-Hoc 虚拟数仓的 n8 和 n9 两个 coordinator(或其中一个)注册到 BI 报表虚拟数仓相同的 zookeeper 地址下,分摊 BI 报表的查询负载。
与混合分组相比,分时复用功能仅适合在规格相似的节点组之间使用,确保不同分组上的查询性能没有明显的差距。
4.3 基于负载的节点选择
executor 节点会出现多种原因导致计算资源使用不均衡的问题,比如数据倾斜导致某些 executor 节点需要消耗更多计算资源扫描和处理数据,或引入混合分组特性导致某些节点组上节点负载过高等等。
针对该问题,NDH Impala 进行了两个优化。第一个是支持基于 executor 节点负载的查询分布式执行,实现方法为在为查询 SQL 确定分布式执行计划时,考虑 executor 节点当前可用的计算资源情况,剔除可用资源较少的 executor 节点;第二个是存在多队列时,限制同个队列上的查询请求在一个 executor 上的资源使用总量,避免 executor 资源被某个队列独占。
5 小结
本小节主要介绍了虚拟数仓概念的来源和实现,重点分析了 NDH Impala 在虚拟数仓这块的探索、思考和使用。目前虚拟数仓在网易互联网业务以及网易数帆的商业化客户集群上均有成功的应用案例。
笔者认为,虚拟数仓应该是新一代分析性数仓必备的一个能力,它能够剥离复杂多样的业务负载,充分发挥执行引擎自身的能力。最后需要指出的是,虚拟数仓是一种云原生的特性,计算资源能够灵活伸缩的环境能够最大化其价值。
作者简介
荣廷,网易数帆数据库技术专家,10 年 + 数据库相关工作经验,目前主要负责高性能数仓和云原生数据库研发工作。