CDP Impala的准入控制架构

介绍

Apache Impala Cloudera 支持的大规模并行内存SQL 引擎,专为分析和针对存储在Apache HiveApache HBase Apache Kudu 表中的数据的即席查询而设计。支持强大的查询和高并发性Impala 可以使用大量的集群资源。在多租户环境中,这可能会无意中影响相邻的服务,例如YARNHBase甚至 HDFS。大多数情况下,这些相邻的服务可以通过启用静态服务池来隔离它使用 Linux cgroups 来修复每个服务的CPU 和内存分配。这些可以使用Cloudera Manager 向导进行简单配置。然而,Impala准入控制通过将查询引导到离散资源池中以实现工作负载隔离、集群利用率和优先级排序,从而在Impala 内实现细粒度的资源分配。

这篇博文将努力:

·      解释Impala的准入控制机制; 

·       提供资源池配置的最佳实践;

·       提供针对现有工作负载调整资源池配置的指南。

Impala 查询执行剖析

在我们详细研究准入控制之前,让我们快速概述一下Impala 查询执行。Impala实现了一个 SQL 查询处理引擎,它基于充当工作线程和协调器的守护进程集群。客户端将其查询提交给协调器,该协调器负责在集群的工作线程之间分配查询执行。 

Impala 查询处理可以分为三个阶段:编译、准入控制和执行,如下图所示:

CDP Impala的准入控制架构

编译

Impala 协调器收到来自客户端的查询时,它会解析查询,将查询中的表和列引用与Impala 目录服务器管理的架构目录中包含的数据统计信息对齐,然后对查询进行类型检查和验证。 

使用表和列统计信息,协调器生成优化的分布式查询计划- 关系运算符树 - 具有可并行化的查询片段。它将查询片段分配给工作人员,考虑到数据局部性——从而形成片段实例——并估计查询的每个主机主内存消耗的峰值。它进一步确定了工作人员在接收他们的片段时最初将分配用于处理的主内存的分配。

准入控制

编译后,协调器将查询提交给准入控制。准入控制基于主内存估计和片段分配以及已经准许进入集群的查询来决定查询是被准许执行、排队还是拒绝。

为此,它会在每个主机每个集群的基础上保留一个估计被承认的查询消耗的主内存的计数——后者被划分为由集群管理员定义的所谓的资源池。如果查询有足够的空间来适应每个主机和每个资源池的计数,它将被允许执行。

准入控制的关键指标是查询的MEM_LIMIT:查询的每台主机内存消耗允许的最大值。MEM_LIMIT通常——但并不总是我们稍后会看到的——与查询编译阶段估计的每个节点内存消耗峰值相同。

执行

准入后,协调器开始执行查询。它将片段实例分发给工作程序,收集部分结果,组装总结果,并将其返回给客户端。 

工作程序从查询编译阶段确定的初始主内存预留开始执行。随着执行的进行,工作人员可能会严格遵守准入控制所允许的MEM_LIMIT 来增加为查询分配的内存。如果查询的主内存消耗接近这个限制,它可能会决定将内存溢出到磁盘(如果允许的话)。如果主内存消耗达到MEM_LIMIT,则查询将被终止。

在执行期间,协调器会监视查询的进度并记录详细的查询配置文件。查询配置文件将比较查询编译阶段的估计行数和主内存消耗与查询实际消耗的行数和主内存。这为查询优化和表统计的质量提供了宝贵的见解。

Impala 准入控制详解

在对 Impala 查询执行的一般概述之后,让我们深入了解Impala 准入控制。准入控制主要由 

·       分配给每个守护进程的主内存(mem_limit配置参数);

·       分配给资源池的总集群内存份额及其配置;

·       查询计划器的总内存消耗和每个主机的内存消耗估计。

让我们看一下关键资源池配置参数和查询的准入控制过程的具体示例。

资源池

资源池允许将 Impala 集群内存总量划分为不同的用例和租户。分段不是在公共池中运行所有查询,而是允许管理员将资源分配给最重要的查询,以便它们不会被业务优先级较低的查询中断。

关键的资源池配置参数是:

·       Max Memory:集群中可以允许池中运行的查询的总主内存量。如果在池中已运行的查询的预期总主内存之上,将被允许进入池的查询的预期总主内存消耗超过此限制,则查询将不被允许。查询可能会被拒绝或排队,具体取决于池的队列配置。

·       最大查询内存限制查询允许的最大每台主机内存消耗的上限 (MEM_LIMIT)。准入控制永远不会对查询施加大于最大查询内存限制的 MEM_LIMIT - 即使查询编译阶段估计的每个主机内存消耗峰值超过此限制。与 Max Memory 不同,Maximum Query Memory Limit 影响所有池的准入控制。即,如果在已经运行的查询的 MEM_LIMIT 之上的查询的MEM_LIMIT(受最大查询内存限制限制)超过给定守护程序的配置主内存 mem_limit,则该查询将不被接受。

·       此参数的目的是限制查询对准入控制的大且可能不好或过于保守的峰值每主机内存消耗估计的影响 - 例如,基于没有统计信息的表或非常复杂的查询的查询。此参数与 Max Memory、守护进程的数量以及守护进程的 mem_limit 配置相结合,分别隐式地定义了在池中和跨池中运行的查询的潜在并行度。根据经验,最大查询内存限制应该是最大内存除以捕获所需查询池并行度的守护进程数量的一部分。

·       最小查询内存限制查询允许的最大每台主机内存消耗的下限 (MEM_LIMIT)。无论每个主机的内存估计如何,MEM_LIMIT 都不会小于此值。最小查询内存限制的安全值为每个节点 1GB

·       Clamp MEM_LIMIT:客户端可以通过将MEM_LIMIT 查询选项显式设置为不同的值(例如,通过在其查询前添加SET MEM_LIMIT=...mb)来覆盖由查询编译估计的每个主机内存消耗峰值以及由准入控制派生的结果MEM_LIMIT . 如果 Clamp MEM_LIMIT 未设置为 true(这是默认值),则用户可以完全忽略资源池的最小和最大查询内存限制设置。如果设置为 true,则客户端明确提供的任何 MEM_LIMIT 都将绑定到最小和最大查询内存限制设置。

·       Max Running Queries:虽然最小和最大查询内存限制设置与最大内存设置和守护进程的数量一起隐含地定义了一个资源池内可以并行运行的查询数量的范围,但最大运行查询允许定义一个固定的可以同时运行的查询数。

·      Max Queued Queries:如果一个查询不能被立即接纳,因为它的MEM_LIMIT 会超过池的最大内存限制或守护进程的mem_limit 配置参数,Impala 准入控制可以将查询发送到池的等待队列。Max Queued Queries 定义了这个队列的大小,默认为200。如果队列已满,查询将被拒绝。

·      队列超时:查询在被拒绝之前可以在池的等待队列中等待多长时间的限制。默认超时为一分钟。

准入控制示例

让我们使用一个简化的示例来说明Impala 准入控制以及每个主机的峰值内存消耗估计和资源池设置之间的相互作用:

CDP Impala的准入控制架构

在上图中,客户端通过示例资源池P2 Impala 协调器提交了一个简单的 group by / count 聚合SQL 查询。使用正在查询的表的架构目录和查询统计信息,查询规划器估计每台主机的峰值内存使用量为570 MiB。此外,规划器已确定查询的片段将在主机wn001wn002wn-003 wn004 上执行。有了这个查询编译结果,查询就被移交给准入控制。

出于示例的目的,我们假设资源池P2 已配置为 2000 MiB的最大查询内存限制、500MiB的最小查询内存限制和6000MiB 的最大内存设置。

每个主机的峰值内存消耗估计为570MiB,正好符合最小和最大查询内存限制设置。因此,准入控制不会以任何方式修改此估计值,而是将MEM_LIMIT 设置为570 MiB。如果估计值高于2000MiB,则MEM_LIMIT 将被限制为2000MiB;如果估计值低于500MiB,则MEM_LIMIT 将被缓冲到500MiB

对于准入,准入控制检查节点wn001wn002wn-003 wn004 上已经运行的查询的所有MEM_LIMIT 总和加上570 MiB 是否超过这些节点配置的主内存mem_limit 中的任何一个。 

准入控制进一步检查查询的MEM_LIMIT 乘以查询将在已经运行的查询之上运行的节点数是否仍然符合P2 配置的 6000 MiB的最大内存设置。

如果两个检查中的任何一个失败,准入控制将排队或拒绝查询,具体取决于是否已达到等待队列限制。

如果两个检查都通过,准入控制允许查询在570MiB MEM_LIMIT 下执行。只要每个工作节点在节点上消耗的主内存不超过此限制,它就会执行查询——如果是这种情况,工作节点将终止查询。

准入控制最终将受影响节点的主机内存准入计数增加MEM_LIMIT (570MiB);它还将通过查询将在MEM_LIMIT (570MiB * 4 = 2280 MiB) 上运行的节点数增加资源池的集群内存。

准入控制最佳实践

在说明了 Impala 准入控制的工作原理之后,问题是通过资源池配置准入控制以适应自己的工作负载的合理策略是什么。

通过调整准入控制,人们试图在几个目标之间取得平衡,核心目标是:

·      工作负载隔离;

·      集群资源利用率;

·      快速查询录取。

在下文中,我们提出了使用可用的Impala 准入控制配置选项实现这些目标的基本建议。请注意,某些推荐的优化策略被重复以实现不同的目标。

在这些建议中,我们提到了集群参数以及工作负载特征。我们首先列出集群的基本参数和在确定准入控制配置时应该收集的预期工作负载。

集群和工作负载参数

以下基本集群参数会影响Impala 准入控制的各种配置选项:

·      集群中Impala 工作进程的数量;

·      为这些工作人员配置的每节点内存mem_limit

·      Impala 集群的最终最大内存(workers * mem_limit)。 

·       在所有池中运行的并发查询总数。

参数化工作负载不太明确。通常,在准入控制配置时不知道确切的工作负载特征,它们可能会随时间变化,或者难以量化。但是,管理员应该考虑:

·      Impala 上运行的应用程序

·       Impala 上运行的工作负载类型

·      查询并行度

·      可接受的等待时间 

·      内存消耗

Cloudera Manager 通过 Impala > Queries 页面在这方面提供了一些有用的见解:

CDP Impala的准入控制架构

在该页面上,可以按方面过滤查询,例如,每个节点的峰值内存使用量以及查询计数:

CDP Impala的准入控制架构

同样,所有节点上查询的峰值内存使用量都有一个直方图:

CDP Impala的准入控制架构

使用此信息,管理员可以迭代资源池配置并开始优化队列配置以最好地满足业务需求的过程。通常,随着使用知识和洞察力的发展,将需要多次迭代。

实现工作负载隔离

保持池同质:为了隔离工作负载,保持资源池同质很有用。也就是说,池中的查询本质上应该是相似的,无论它们是需要偶尔分配大内存的临时分析,还是高度调整的常规ELT 查询。

根据相对负载设置资源池的最大内存:确定资源池后,为每个池确定的第一个配置参数是最大内存。您可能还记得,这是整个Impala 工作程序主内存的份额,允许控制允许查询进入池。

选择最大内存的一种简单方法是将其设置为应授予池中查询的相对负载份额。例如,可以基于预期或展示的查询率或内存使用量来量化相对负载份额。

避免拥有太多资源池:拥有太多资源池也不理想,因为该池的Impala 内存已被保留,其他池无法使用该内存(除非该池被过度配置)。这基本上会导致繁忙的池排队并且空闲池中的内存未被使用。理想情况下,如果最大和较小的租户可以共享资源池,则取决于大约10 个池的用例。

不要陷入隔离谬误:回想一下,资源池不提供完整的工作负载隔离。这样做的原因是准入控制保持每个主机对所有准许执行的查询的MEM_LIMIT 进行统计的方式。该计数与资源池无关。但是,正如我们将在下面看到的,您可以降低录取被拒绝的可能性。

保持最大查询内存限制低:通过减少每个资源池的最大查询内存限制,所有被承认的查询的MEM_LIMITs 达到工作人员的mem_limit 的可能性降低。 

启用Clamp MEM_LIMIT如果没有为资源池启用 Clamp MEM_LIMIT,则每个向该池提交查询的用户都可以强制准入控制设置MEM_LIMIT,即使在池的最小查询内存限制和最大查询内存限制的范围之外。因此,通过在查询前添加SET MEM_LIMIT=<very large value>,恶作剧的用户可以快速阻止准入控制,不仅允许进一步查询进入同一个池,而且阻止来自其他池的其他查询到同一个工作进程守护进程。

计算表统计数据:使用当前统计数据这样做会产生更好的——即更低的——查询规划器对每台主机内存的估计,这是准入控制的MEM_LIMIT 的基础。此外,查询计划将被优化,这将导致改进的执行时间。更快的执行时间意味着在准入控制中阻塞内存的时间更少。

避免将查询溢出到磁盘:溢出到磁盘的查询会显着降低查询速度。慢查询会在较长时间内阻塞准入控制中的内存,这增加了阻塞其他查询准入的可能性。因此,设置积极的(最小的)SCRATCH_LIMITS 以确保此类查询被快速终止,条件是在某些情况下,溢出到磁盘是不可避免的。通常,管理溢出的主要策略是通过管理统计信息、文件格式和布局来确保查询不会首先溢出。禁用不安全溢出将确保可能达到该限制的查询被快速终止。 

可以设置SCAN_BYTES_LIMIT 来控制扫描100 个分区的查询和NUM_ROWS_PRODUCED_LIMIT 以避免设计不良的查询- 例如交叉连接,但是在普遍设置这些限制时应该谨慎,因为在每个查询或每个池级别设置可能更合适,并且反映集群的运行特性和容量。有关 更多信息,请参阅CDP 私有云基础文档

设置最大运行查询数以限制并行度:由于许多查询以不受控制的方式提交到池中,过于宽松的并行度边界可能会允许这些查询填满每个主机允许的内存计数,从而阻止其他池中的查询跑步。通过将Max Running Queries 参数设置为池工作负载所需的查询并行度,可以为来自其他池的查询创建每台主机内存计数的空间。这应该伴随适当的等待队列设置(最大排队查询和队列超时)。

实现高集群资源利用率

保持最大查询内存限制接近每节点查询内存消耗峰值:保持最大查询内存限制接近每节点内存消耗的实际峰值对于实现良好的集群内存利用率非常重要。

记住 Impala 准入控制不考虑查询的实际内存消耗。相反,它根据受最小和最大查询内存限制值约束的查询规划器内存估计,通过MEM_LIMIT 管理准入。池的最大查询内存设置得越慷慨,准入控制就越愿意考虑和信任规划器的大量保守内存估计,这可能会导致- 例如 - 丢失或过时的表统计信息或非常复杂的查询计划。

仅在必要时限制并行度:尽管其他资源池中的负载有限,但在准入控制不再允许查询进入已达到其运行查询限制的池的情况下,设置最大运行查询会导致集群利用率降低。因此,查询并行性应该只针对查询摄取率高突发或许多长时间运行的查询的池进行明确限制。

集群级别查询并行限制:在集群级别,在所有池中,建议在任何时间运行的总查询数建议接近数据节点上多线程内核总数的1.5 2.x。这可确保每个查询都获得适当的CPU 时间份额,并且不会频繁地被调出。因此,如果数据节点有2*24 个核心处理器,那么通过多线程,我们有96 个多线程核心。 

有了这个,我们建议在任何给定时间集群上的并发查询总数不应超过96 个查询。

实现快速查询准入

理想的查询准入控制应该几乎不会被客户端注意到,但仍能确保工作负载隔离和高度的集群利用率。然而,客户端特别明显的一个影响是,当Impala 准入控制不承认查询进入集群,而是将其放入等待队列中,甚至可能超时。 

设置一个较低的最大查询内存限制:不仅降低了每个主机承认的内存计数达到工作线程的mem_limit 的风险;它还使查询消耗更少的池的最大内存本身,再次降低了等待时间的风险。在大多数情况下,1GiB是一个合理的低值。

启用Clamp MEM_LIMIT ,这样查询作者不能有意或无意地为他们的查询设置过大的MEM_LIMITs 准入控制。

确保当前的表统计信息:支持查询计划器以较低的内存估计创建更好更快的查询计划。 

限制溢出查询:由于这些查询速度很慢,会在很长一段时间内给每个池承认的内存计数带来负担,从而对查询不被允许进入集群的风险产生负面影响。溢出增加了磁盘的工作,减慢了查询的读取速度,这是您强烈希望避免的事情

考虑每个池的等待时间弹性:实际上,必须在查询摄取率突发或长时间运行的查询的池查询的等待时间与具有不同查询特征和要求的其他池的查询的等待时间之间取得平衡。从一个应用程序的角度来看,快速查询准入可能构成从另一个应用程序的角度来看的次优工作负载隔离。

为了能够为资源池进行等待队列配置,因此了解向这些资源池发出查询的不同应用程序可接受的准入等待时间是很重要的。

总结

总之,我们已经演示了Impala 查询的剖析,它是如何计划、编译和允许执行的,以及管理员如何使用查询配置文件来调整和优化查询的资源使用。我们已经描述了Impala 准入控制以及如何使用它来分割Impala 服务资源并进行调整,以便根据业务优先级安全执行满足既定要求的查询。此处提供更多文档。 

 

原文作者: Niel DunnageUtz Westermann

原文链接:https://blog.cloudera.com/admission-control-architecture-for-cloudera-data-platform/

 

上一篇:如何将您的数据中心变成真正的私有云


下一篇:java进制转换代码