Impala的可伸缩性注意事项
本节介绍了您的群集大小和数据量如何影响Impala表的SQL性能和架构设计。通常,增加更多的群集容量可以减少由于内存限制或磁盘吞吐量而造成的问 另一方面,较大的群集更可能具有其他类型的可伸缩性问题,例如导致查询性能问题的单个缓慢节点。
有关可伸缩性和性能调整的一个很好的技巧来源是Impala Cookbook演示文稿。这些幻灯片会随着新功能的出现和新基准的执行而定期更新。
许多表或分区对Impala目录性能和内存使用的影响
由于HadoopI / O针对读取和写入大型文件进行了优化,Impala针对包含相对较少的大型数据文件的表进行了优化。包含数千个表的模式或包含数千个分区的表可能遇到启动期间或DDL操作期间的性能问题,例如改变表 声明。
重要:
由于CDH5.7 / Impala 2.5及更高版本中的catalogd守护程序的默认堆大小发生更改,因此升级到CDH 5.7 / Impala 2.5后,可能需要执行以下步骤来增加 目录化内存限制,即使以前不需要。
对于具有大量表,分区和数据文件的模式,catalogd守护进程可能会遇到内存不足错误。要增加catalogd守护进程的内存限制,请执行以下操作:
1. 通过在守护程序在群集上运行的主机上运行以下命令来检查catalogd守护程序的当前内存使用情况:
2. jcmd catalogd_pid VM.flags
3. jmap -heap catalogd_pid
4. 为目录堆决定足够大的值。您将其表示为一个环境变量值,如下所示:
5. JAVA_TOOL_OPTIONS = “ - Xmx8g”
6. 在由Cloudera Manager管理的系统上,将此值包含在目录服务器的Java堆大小 (ClouderaManager 5.7和更高版本)或Impala Catalog Server环境高级配置代码段(安全阀)(Cloudera Manager 5.7之前)中。然后重新启动Impala服务。
7. 在不受Cloudera Manager管理的系统上,将此环境变量设置放入catalogd守护程序的启动脚本中,然后重新启动 catalogd守护进程。
8. 使用与之前相同的jcmd和jmap命令验证新设置是否有效。
Impala Statestore的可伸缩性注意事项
在CDH5.3之前,statestore只向其用户发送一种消息。此消息包含订阅者订阅的所有主题的所有更新。它也使用户知道状态存储没有失败,相反,状态存储使用向用户发送心跳的成功来决定用户是否失败。
在单个消息中组合主题更新和故障检测导致了具有大量表,分区和HDFS数据块的群集中的瓶颈。当状态存储过载并传输元数据更新时,心跳消息发送的频率较低,有时会导致用户超时与状态存储区建立连接。增加用户超时和减少状态存储心跳的频率解决了这个问题,但降低了状态存储失败或重新启动时的响应能力。
从CDH5.3开始,状态存储现在会在单独的消息中发送主题更新和检测信号。这允许状态存储发送和接收稳定的轻量级心跳流,并且消除了根据固定调度发送主题更新的需求,减少了状态存储网络开销。
statestore现在具有statestored守护进程的以下相关配置标志:
-statestore_num_update_threads
statestore中专用于发送主题更新的线程数。您通常不需要更改此值。
默认: 10
-statestore_update_frequency_ms
statestore尝试向每个订户发送主题更新的频率(以毫秒为单位)。这是一个尽力而为的价值; 如果状态存储不能满足这个频率,它会尽可能快地发送主题更新。您通常不需要更改此值。
默认值: 2000
-statestore_num_heartbeat_threads
statestore中专用于发送心跳的线程数。您通常不需要更改此值。
默认: 10
-statestore_heartbeat_frequency_ms
statestore尝试向每个用户发送心跳的频率(以毫秒为单位)。这个值应该适用于大型目录并且最多可以聚集大约150个节点。除此之外,您可能需要增加此值,以使心跳消息之间的间隔更长。
默认值: 1000(每秒一个心跳消息)
从CDH5.3开始,Cloudera Manager用户界面中并不是所有这些标志都存在。一些必须使用Statestore组件的高级配置代码段字段进行设置。
如果集群启动花费很长时间,并且一直显示黑斑羚这个Impala守护进程没有准备好接受用户请求,状态存储可能花费太长时间才能将整个目录主题发送到群集。在这种情况下,考虑添加--load_catalog_in_background = FALSE到您的目录服务配置。此设置会停止状态存储在群集启动时将整个目录加载到内存中。而是在第一次访问表时加载每个表的元数据。
SQL操作溢出到磁盘
当Impala接近超过特定主机的内存限制时,某些内存密集型操作会将临时数据写入磁盘(称为溢出到磁盘)。
结果是成功完成的查询,而不是失败的内存不足的错误。由于额外的磁盘I / O写入临时数据并重新读取,权衡是降低的性能。放缓可能是显着的。因此,虽然此功能可以提高可靠性,但应优化查询,系统参数和硬件配置,以使这种情况极少出现。
什么类型的查询可能会泄漏到磁盘上:
几个SQL子句和构造需要内存分配,可以激活溢出机制:
· 当一个查询使用一个 通过...分组 子句中包含数百万或数十亿个不同值的列,Impala会在内存中保留相似数量的临时结果,以累计组中每个值的聚合结果。
· 将大表连接在一起时,Impala将内存中的一个表的联接列的值保留,以便将其与另一个表中的传入值进行比较。
· 当一个大的结果集被排序的时候 ORDER BY 子句中,每个节点将其结果集的一部分排序在内存中。
· 该 不同 和 联盟 运算符构建内存中的数据结构以表示迄今为止发现的所有值,以消除查询过程中的重复。
为查询中的连接节点激活泄漏到磁盘功能时,Impala不会为该主机上的连接操作生成任何运行时筛选器。查询中的其他连接节点不受影响。
Impala如何处理暂存磁盘空间以进行溢出:
缺省情况下,大排序,连接,聚合或分析函数操作期间使用的中间文件存储在/ tmp /impala-scratch目录中。操作完成后,这些文件将被删除。(多个并发查询可以执行使用“溢出到磁盘” 技术的操作,这些临时文件没有任何名称冲突。)您可以通过启动impalad后台程序来指定其他位置--scratch_dirs =“ path_to_directory ”配置选项或Cloudera Manager用户界面中的等效配置选项。您可以指定单个目录或逗号分隔的目录列表。暂存目录必须位于本地文件系统中,而不是HDFS中。您可以为不同的主机指定不同的目录路径,具体取决于可用存储设备的容量和速度。在CDH5.5 / Impala 2.3或更高版本中,如果Impala无法在其中一个临时目录中创建或读取和写入文件,Impala将成功启动(并向其写入警告)。如果该目录所在的文件系统的可用空间少于1 GB,则Impala仍会运行,但会向其日志中写入警告消息。如果Impala在查询期间读取或写入临时目录中的文件时遇到错误,Impala将记录错误,并且查询失败。
SQL操作符的内存使用情况:
溢出功能的基础结构影响受影响的SQL运算符的方式,例如 通过...分组, 不同,并加入,使用内存。在参与查询的每个主机上,查询中的每个这样的操作符在构建数据结构以累积内存时处理聚合或连接操作。使用的内存量取决于该主机处理的数据部分,因此可能会因主机而异。当特定主机上的操作员使用的内存量达到阈值时,Impala会预留一个额外的内存缓冲区以用作工作区,以防操作员使查询超出该主机的内存限制。分配内存缓冲区后,该操作符使用的内存基本保持稳定或仅缓慢增长,直到达到内存限制点,并且查询开始将临时数据写入磁盘。
在Impala2.2(CDH 5.4)之前,可能会溢出到磁盘的操作员的额外内存缓冲区在适用的SQL操作员使用的数据结构达到16 MB时分配,内存缓冲区本身为512 MB。在Impala 2.2中,这些值减半:阈值为8 MB,内存缓冲区为256 MB。在Impala2.3 / CDH 5.5及更高版本中,缓冲区的内存将按需分配,以避免内存使用突然大幅跳跃。使用多个此类运算符的查询可能会分配多个此类内存缓冲区,因为每个运算符的数据结构大小超过了特定主机上的阈值。
因此,处理每个主机上相对较少数据量的查询可能永远达不到任何运算符的阈值,并且永远不会分配任何额外的内存缓冲区。一个处理了数百万个组,不同的值,连接键等的查询可能会跨越门槛,导致其内存需求突然上升,然后变平。集群越大,在任何特定主机上处理的数据就越少,从而减少了需要额外内存分配的机会。
添加在:此功能已添加到ORDER BYImpala 1.4中CDH 4和CDH 5.1中的条款。此功能已扩展到适用于CDH 4的Impala 2.0和CDH5.2中的连接查询,聚合函数和分析函数。在Impala 2.2(CDH 5.4)中,每个操作员所需的内存工作区的大小从512 MB减少到256 MB。
避免查询泄露到磁盘:
由于额外的I / O可能会对这些类型的查询强加显着的性能开销,请尝试通过使用以下步骤来避免这种情况:
1. 检测查询溢出到磁盘的频率以及写入多少临时数据。请参阅以下资源:
o 的输出 简介命令在impala-shell解释器。这些数据显示了每台主机的内存使用情况以及整个集群的内存使用情况。该BlockMgr.BytesWritten 计数器报告在查询期间有多少数据写入磁盘。
o Cloudera Manager中的“ Impala查询”对话框。您可以在群集中的所有节点上查看查询的峰值内存使用情况。
o Impala调试Web用户界面中的“ 查询”选项卡。选择要检查的查询,然后单击相应的配置文件链接。这些数据可以分解群集中的单个主机的内存使用情况,这是您连接到其Web界面的主机。
2. 使用一种或多种技术来减少查询溢出到磁盘的可能性:
o 如果可行的话,请增加Impala内存限制,例如,如果可以增加可用内存的次数超过在特定节点上写入磁盘的临时数据量。请记住,在Impala 2.0及更高版本中,您可以发布SET MEM_LIMIT 作为SQL语句,可以让您调整JDBC和ODBC应用程序查询的内存使用情况。
o 增加集群中的节点数量,以增加Impala可用的聚合内存,并减少每个节点上所需的内存量。
o 在硬件级别增加每个DataNode的整体内存容量。
o 在Impala和其他Hadoop组件之间共享资源的集群上,使用资源管理功能为Impala分配更多内存。有关详细信息,请参阅Impala的资源管理。
o 如果内存压力是由于运行许多并发查询而不是少量内存密集型查询造成的,请考虑使用Impala许可控制功能来降低并发查询数的限制。通过排除大部分资源密集型查询,可以避免内存使用量激增,并缩短整体响应时间。有关详细信息,请参阅准入控制和查询排队。
o 使用以下一种或多种技术调整内存要求最高的查询:
§ 运行 计算统计 语句,用于涉及大规模连接和聚合查询的所有表。
§ 最小化你的使用 串连接列中的列。优先使用数字值。
§ 检查 说明计划了解用于最耗费资源的查询的执行策略。有关详细信息,请参阅使用EXPLAIN计划进行性能调整。
§ 如果即使有统计信息可用,Impala仍然选择次最佳执行策略,或者如果统计信息不能及时更新以适应大型或快速更改的表,则可以向最耗费资源的查询添加提示以选择正确的执行策略。有关详细信息,请参阅Impala SELECT语句中的查询提示。
o 如果您的查询由于溢出而出现大量性能开销,请启用 DISABLE_UNSAFE_SPILLS查询选项。此选项可防止内存使用量可能过高的查询溢出到磁盘。有关详细信息,请参阅DISABLE_UNSAFE_SPILLS查询选项(仅限CDH 5.2或更高版本)。在使用上述步骤调整有问题的查询时,通过此选项设置可以取消越来越少的查询。
测试溢出到磁盘的性能影响:
要人为地引发溢出,要测试此功能并了解性能影响,请使用内存限制为至少2 GB的测试环境。发行组 没有参数的命令来检查当前的设置 MEM_LIMIT查询选项。设置查询选项DISABLE_UNSAFE_SPILLS =真。此选项限制了溢出到磁盘的功能,以防止从预先知道的查询中失控磁盘使用不理想。在impala-shell中,根据前面解释的标准运行一个您期望内存密集的查询。大桌子的自我加入是一个不错的选择:
从big_table中选择count(*)a join big_table b using(column_with_many_values);
发行 简介命令在查询期间获得每个节点上的内存使用情况的详细分类。关于内存的配置文件输出的关键部分是BlockMgr一部分。例如,此配置文件显示查询没有完全超出内存限制。
BlockMgr:
- BlockWritesIssued:1
- BlockWritesOutstanding:0
- BlocksCreated:24
- BlocksRecycled:1
- BufferedPins:0
- MaxBlockSize:8.00 MB(8388608)- MemoryLimit:200.00 MB(209715200)- PeakMemoryUsage:192.22 MB(201555968)
- TotalBufferWaitTime:0ns
- TotalEncryptionTime:0ns
- TotalIntegrityCheckTime:0ns
- TotalReadBlockTime:0ns
在这种情况下,由于内存限制已经低于任何建议值,我增加了查询的数据量,而不是进一步减少内存限制。
设置 MEM_LIMIT查询选项设置为小于配置文件输出中报告的峰值内存使用率的值。不要指定低于大约300MB的内存限制,因为如此低的限制,查询可能由于其他原因而无法启动。现在再次尝试内存密集型查询。
检查查询是否失败,并显示如下消息:
警告:对于没有统计信息的计划,已经禁用了溢出功能,并且没有提示
可以防止潜在的错误计划使用太多的群集资源。计算
这些表的统计数据,提示计划或通过查询选项禁用此行为以启用溢出。
如果是这样的话,查询可能消耗了大量的临时磁盘空间,速度变慢,以至于无法在合理的时间内完成。在这种情况下,不要依赖溢出到磁盘的功能,请发出计算统计您的示例查询中的一个或多个表的语句。然后再次运行查询,再次检查高峰内存使用情况 简介 输出,并在必要时再次调整内存限制,使其低于峰值内存使用量。
此时,您有一个需要大量内存的查询,但Impala可以高效地对其进行优化,以便内存使用不会过高。你已经通过设置了一个人为约束MEM_LIMIT选项,以便查询通常会失败并显示内存不足的错误。但是自动溢出到磁盘的功能意味着查询应该实际上成功,代价是一些额外的磁盘I / O读取和写入临时工作数据。
再次尝试查询,并确认它成功。检查简介再次输出。这一次,查找这种形式的行:
- SpilledPartitions:N
如果您看到N大于0的任何这样的行,表示该查询在2.0之前的Impala发行版中将失败,但现在因为溢出到磁盘功能而成功。检查所花费的总时间AGGREGATION_NODE 或包含非零的其他查询片段 SpilledPartitions值。比较时间相似的片段,没有泄漏,例如在简介当相同的查询以更高的内存限制运行时输出。这给你一个具有特定内存限制的特定查询的溢出操作的性能损失的概念。如果将内存限制略低于峰值内存使用量,则查询只需将少量临时数据写入磁盘。设置内存限制越低,写入的临时数据越多,查询变得越慢。
现在对您的环境中使用的实际查询重复此过程。使用DISABLE_UNSAFE_SPILLS 通过设置来确定由于相关表和列缺少统计信息而导致查询使用的内存超过必要量的情况 计算统计 在必要时。
何时使用DISABLE_UNSAFE_SPILLS:
你可能会想,为什么不离开 DISABLE_UNSAFE_SPILLS一直打开。使用此选项的频率和频率取决于您的系统环境和工作负载。
DISABLE_UNSAFE_SPILLS适用于具有特定查询的环境,其性能特征和存储器使用情况未预先知晓。它可以防止不必要地使用大量内存的“最坏情况”查询。因此,您可以在开发新的SQL代码的同时在会话中打开此选项,即使已经关闭了现有的应用程序。
表格和列统计信息通常是最新的组织可能会一直打开此选项,以避免未经测试的查询的最坏情况或者ETL管道中的问题导致没有统计信息的表。打开DISABLE_UNSAFE_SPILLS让你在这种情况下“快速失败”,并立即收集统计数据或调整有问题的查询。
有些组织可能会关闭此选项。例如,你可能有足够大的表格计算统计加载新数据后重新运行是不切实际的。如果你已经检查了说明 你的查询计划,并知道他们正在高效运作,你可以离开 DISABLE_UNSAFE_SPILLS关掉。在这种情况下,你知道任何溢出的查询都不会因为内存消耗而过度。
查询大小和复杂度的限制
对查询的最大大小和复杂性有硬编码的限制。目前,查询中表达式的最大数量是2000个。您可能会超出业务智能工具或其他查询生成器生成的大量或深度嵌套查询的限制。
如果您有能力自定义这样的查询或生成这些查询的查询生成逻辑,请使用单个操作符(如。)替换重复表达式的序列 在 要么 之间可以表示多个值或范围。例如,而不是大量的要么 条款:
其中val = 1或val = 2或val = 6或val = 100 ...
使用单一的 在 条款:
VAL IN(1,2,6,100,...)
Impala I / O的可伸缩性注意事项
Impala积极地并行化其I / O操作,因此可以将更多的磁盘连接到每个主机,效果会更好。Impala在大块上使用批量读取操作很快地从磁盘中检索数据,大多数查询都是CPU绑定的而不是I / O绑定的。
因为那种顺序扫描通常由黑斑羚的查询做的不从固态硬盘的随机存取能力中获益多少,旋转磁盘通常提供最具成本效益的一种存储用于因帕拉数据,很少或根本没有性能损失相比,固态硬盘。
YARN,Llama和准入控制等资源管理功能通常会限制高并发环境中内存,CPU或查询总数。目前,Impala I / O没有限制机制。
表格布局的可伸缩性注意事项
由于检索和在metastore更新数据库表中的元数据的开销,尽量限制在一个表中的列数为最多约2000虽然因帕拉可以处理比这更广泛的表,metastore开销会变得显著,导致根据实际的数据量,查询性能比预期的要慢。
为了尽量减少与Metastore数据库和Impala查询计划相关的开销,请尝试将任何分区表的分区数限制为几万个。
Kerberos相关的大型集群网络开销
Impala启动时,或之后 使用kinit刷新,Impala向KDC发送多个同时请求。对于具有100个主机的集群,KDC可能能够在大约5秒内处理所有的请求。对于拥有1000台主机的集群,处理请求的时间大约为500秒。Impala还会与这些Kerberos相关的请求同时发出多个DNS请求。
在处理这些身份验证请求时,任何提交的Impala查询都将失败,出现如下错误:
查询状态:无法打开运输的主机名
(SASL(-1):一般故障:GSSAPI错误:未指定GSS失败
次代码可以提供更多的信息
(不能接触任何KDC的境界“ 境界 ”))
在此期间,KDC和DNS可能对Impala以外的组件的请求做出响应的速度较慢,所以其他安全服务可能会暂时受到影响。
如果遇到此问题,请考虑采取以下一项或多项措施来解决该问题:
· 扩展你的KDC实现来支持更多的负载。联系您的KDC提供商支持来讨论选项。
· 在群集启动之后,通过发出热身查询启动KDC票据获取过程。一个理想的查询是一个SHUFFLE JOIN在两个表之间,以便所有Impala守护进程都尝试与其他所有人进行通信。重复热身查询,直到成功完成。例如,175个节点群集可能需要大约5分钟的时间。
· 为了减少这个频率 使用kinit 更新,启动一组新的身份验证请求,增加 kerberos_reinit_interval配置设置impalad守护进程。目前,不受Cloudera Manager管理的群集的默认值为60分钟,而Cloudera Manager下的默认值为10分钟。考虑使用更高的值,如360(6小时)。
避免HDFS缓存数据的CPU热点
您可以使用HDFS高速缓存功能(在使用Impala的HDFS高速缓存(仅适用于CDH 5.1或更高版本)和Impala中介绍)来减少经常访问的表或分区的I / O和内存复制。
在此功能的早期阶段,您可能已经发现,启用HDFS缓存导致很少或者没有性能改进,因为它可能会导致“热点”:而不是I / O来读取跨群集并行化的表数据, I / O减少,但处理数据块的CPU负载可能集中在单个主机上。
为了避免热点,包括 有复制 条款与 创建表 要么 改变表 使用HDFS缓存的表的语句。这个子句允许多个主机缓存相关的数据块,所以可以共享CPU负载,减轻任何一台主机的负担。有关详细信息,请参阅CREATE TABLE语句和ALTER TABLE语句。
由于Impala计划在不同主机上处理数据块的工作方式,在某些情况下,HDFS高速缓存数据的CPU负载很高的热点仍然可能出现。在CDH 5.7 / Impala 2.5及更高版本中,调度改进意味着HDFS高速缓存数据的工作在为特定数据块缓存复制副本的所有主机中分配得更好。当多个主机拥有数据块的缓存副本时,Impala会将处理该块的工作分配给哪个主机为当前查询做了最少的工作(以读取的字节数计)。如果即使使用基于负载的调度算法,热点仍然存在,则可以启用查询选项SCHEDULE_RANDOM_REPLICA = TRUE进一步分配CPU负载。如果调度算法在决定哪个主机完成最少的工作时遇到问题,则此设置将导致Impala随机选择主机来处理缓存的数据块。