impala查询作业超时分析
版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/979eca668755
生产在线集群impala查询,多个作业超时
现象:
1、业务方反馈impala查询失败,未返回结果;
2、可看到CM页面上大量impala查询语句正在运行,持续时间>5m(已超时,该值为impala admission control的timeout参数,可设置)
【分析过程】
对于一条超时语句,在default队列上进行测试,
名称 最大内存 最大运行查询 最大队列查询 Queue Timeout Default Query Memory Limit
default 100 吉字节 2 200 1 分钟 2 吉字节
执行
[IP:21000] > set request_pool=default;
REQUEST_POOL set to default
对其中一张表做compute stats,得到该表的分区和列数——【COMPUTE STATS可用来收集涉及到的所有表的统计信息,并让Impala基于每一个表的大小、每一个列不同值的个数、等等信息自动的优化查询,impala查询时计算内存消耗会更加准确】
[IP:21000] > compute stats gl_hisdb.tbl_orhis_trans_log;
Query: compute stats gl_hisdb.tbl_orhis_trans_log
+--------------------------------------------+
| summary |
+--------------------------------------------+
| Updated 143 partition(s) and 61 column(s). |
+--------------------------------------------+
Fetched 1 row(s) in 74.17s
[IP:21000] > show table stats gl_hisdb.tbl_orhis_trans_log; (做了compute stats之后的表)
Query: show table stats gl_hisdb.tbl_orhis_trans_log
+--------------+----------+--------+----------+--------------+-------------------+---------+-------------------+----
| hp_settle_dt | #Rows | #Files | Size | Bytes Cached | Cache Replication | Format | Incremental stats | Location |
+--------------+----------+--------+----------+--------------+-------------------+---------+-------------------+----
| 20180813 | 338489 | 1 | 28.92MB | NOT CACHED | NOT CACHED | RC_FILE | false | hdfs://nameservice/user/dw_hbkal/db/gl_hisdb/tbl_orhis_trans_log/hp_settle_dt=20180813 |
…………………………………………
【同时可以做show column stats 表名】
查看执行计划
[IP:21000] > explain SELECT COUNT(*), hp_settle_dt FROM gl_hisdb.tbl_orhis_trans_log GROUP BY hp_settle_dt;
Query: explain SELECT COUNT(*), hp_settle_dt FROM gl_hisdb.tbl_orhis_trans_log GROUP BY hp_settle_dt
+-----------------------------------------------------------+
| Explain String |
+-----------------------------------------------------------+
| Estimated Per-Host Requirements: Memory=132.00MB VCores=2 |
| |
…………
| 00:SCAN HDFS [gl_hisdb.tbl_orhis_trans_log] |
| partitions=143/143 files=144 size=6.35GB |
+-----------------------------------------------------------+
Fetched 16 row(s) in 0.02s
可知,该语句运行所需单节点内存大小132M
手工执行查询语句:
[IP:21000] > SELECT COUNT(*), hp_settle_dt FROM gl_hisdb.tbl_orhis_trans_log GROUP BY hp_settle_dt;
Query: select COUNT(*), hp_settle_dt FROM gl_hisdb.tbl_orhis_trans_log GROUP BY hp_settle_dt
Query submitted at: 2019-01-03 10:27:55 (Coordinator: http://hostname:25000)
ERROR: Rejected query from pool root.default : request memory needed 234.00 GB is greater than pool max mem resources 100.00 GB.
Use the MEM_LIMIT query option to indicate how much memory is required per node. The total memory needed is the per-node MEM_LIMIT times the number of nodes executing the query. See the Admission Control documentation for more information.
[IP:21000] >
查询失败的提示为 request memory needed 234.00 GB is greater than pool max mem resources 100.00 GB.
该查询语句估算需消耗队列234G内存资源,大于该队列内存资源上限100G,因此提示可用资源不足而报错。
应用方在执行该查询前指定了tqueue,该资源队列资源上限为300g,是大于234G的,因此该查询作业可被提交,在impala页面显示为运行状态,但由于tqueue队列上运行的作业往往多个,因此会出现排队现象,而后续作业等待时间在超过queue timeout时间(5分钟)后便会失败。依次类推。
ps:default的Default Query Memory Limit为2G,因此可推算出该查询是分配在234/2=117个节点上运行。集群中共有145个impala daemon,而该表的partitions是143个,非均匀分布在117个节点上。
在动态资源池impala中,有两个参数需关注:第一个参数是资源队列的最大内存;第二个参数是Default Query Memory Limit
第一个参数是对整个资源池进行资源限定,是一个集群范围的限制,它根据每个主机的Default Query Memory Limit(查询内存上限)乘以集群中的IMPALA节点数来确定可以同时安全运行多少查询。
第二个参数引用cloudera官网的一段话:
"That value affects the execution of each query, preventing it from overallocating memory on each host, and potentially activating the spill-to-disk mechanism or cancelling the query when necessary."——该值将会影响每个query的运行,它能尽可能地降低在单个主机上过度的内存分配,还能触发溢写磁盘机制,并在必要时取消query。
简单来说,该值的含义是:每台节点上,每个query的内存限定。
两者需满足如下关系:Default Query Memory Limit*运行impala查询节点数量<资源队列的可用最大内存,这是显然的。
eg:impala daemon节点数有150个,Default Query Memory Limit的值设置为2g,那么分配的query资源队列大小需大于2*150=300g。
若队列资源<300g,该查询可能会提交不上(query需要资源大于资源队列可用内存上限)或处于等待状态(query需要资源虽然小于资源队列可用内存上限,但由于有前序查询,需等待资源释放)。
根据以上,为确保在impala的某个资源池中,能并发运行多个impala作业,需注意两点:
1、指定合适的最大内存设置,即第一个参数值,这是一个集群范围的限制,它根据每个主机的Default Query Memory Limit(查询内存上限)乘以集群中的IMPALA节点数来确定可以同时安全运行多少查询。
2、指定合适的Default Query Memory Limit(根据实际query所需的单节点内存可适当降低)
以生产集群为例,资源队列tqueue的最大内存上限为300g,设置的可同时并行运行的作业数量为50,impala daemon节点数145个,Default Query Memory Limit为2g。
在该设置的情形下,对于一个大表来说,假设查询运行在145个impala daemon节点上,impala估算所需的资源为145*2=290g,临界该资源队列上限,可保证该作业提交;由于设置了并行作业数50,后续提交的作业大概率会因为资源不足而发生等待,当等待时间超过5分钟,作业将会失败。
从之前的执行计划可看出,Estimated Per-Host Requirements: Memory=132.00MB VCores=2 一个查询大约消耗132M内存,设置2g的Default Query Memory Limit偏大,将其调整为1g,那么为保证并行50个作业运行,需设置队列最大内存为1g*145*50=7250g。考虑到实际并行作业并没有这么多,且集群内存还需给到其他服务,可适当降低该值。