带你走进Impala query profile第二篇

    技术2023-10-14  84

    在上一篇文章中(https://blog.csdn.net/Allenzyg/article/details/107105335),我们介绍了Impala query profie的概要部分,在本篇文章我们介绍Profile的查询计划(Query Plan)和执行概要(Execution Summary)部分。

    Profile的查询计划和执行概要如下所示:

    Query Runtime Profile:

    Query (id=2945a77ff619defe:b658730000000000):

      Summary:

        Session ID: 24abae22c723db5:2c0a25a81814e8a8

        Session Type: BEESWAX

        Start Time: 2020-07-03 11:58:47.317039000

        End Time: 2020-07-03 12:12:56.216137000

        Query Type: QUERY

        Query State: FINISHED

        Query Status: OK

        Impala Version: impalad version 2.10.0-cdh5.13.3 RELEASE (build 15a453e15865344e75ce0fc6c4c760696d50f626)

        User: root

        Connected User: root

        Delegated User:

        Network Address: 10.138.232.87:36237

        Default Db: default

        Sql Statement: select count(*) from bms_ldgdb.ldg_690marketization_ledger t where check_flag in (4,-1) and ledger_status = 2 and is_delete = 0 and module in (1,2) and account_date >= '2020-06-01' and industry_code != ''

        Coordinator: rrs-hdp-dn04:22000

        Query Options (set by configuration):

        Query Options (set by configuration and planner): MT_DOP=0

        Plan:

    ----------------

    Max Per-Host Resource Reservation: Memory=0B

    Per-Host Resource Estimates: Memory=20.00MB

    WARNING: The following tables are missing relevant table and/or column statistics.

    bms_ldgdb.ldg_690marketization_ledger

     

    F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1

    |  Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B

    PLAN-ROOT SINK

    |  mem-estimate=0B mem-reservation=0B

    |

    03:AGGREGATE [FINALIZE]

    |  output: count:merge(*)

    |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    02:EXCHANGE [UNPARTITIONED]

    |  mem-estimate=0B mem-reservation=0B

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    F00:PLAN FRAGMENT [RANDOM] hosts=16 instances=16

    Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B

    01:AGGREGATE

    |  output: count(*)

    |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    00:SCAN KUDU [bms_ldgdb.ldg_690marketization_ledger t]

       predicates: industry_code != ''

       kudu predicates: is_delete = 0, ledger_status = 2, check_flag IN (4, -1), module IN (1, 2), account_date >= '2020-06-01'

       mem-estimate=0B mem-reservation=0B

       tuple-ids=0 row-size=15B cardinality=unavailable

    ----------------

        Estimated Per-Host Mem: 20971520

        Tables Missing Stats: bms_ldgdb.ldg_690marketization_ledger

        Per Host Min Reservation: rrs-hdp-dn03:22000(0) rrs-hdp-dn04:22000(0) rrs-hdp-dn05:22000(0) rrs-hdp-dn08:22000(0) rrs-hdp-dn11:22000(0) rrs-hdp-dn13:22000(0)

        Request Pool: root.default

        Admission result: Admitted immediately

        ExecSummary:

    Operator       #Hosts   Avg Time   Max Time  #Rows  Est. #Rows   Peak Mem  Est. Peak Mem  Detail

    ----------------------------------------------------------------------------------------------------------------------------------

    03:AGGREGATE        1  316.053us  316.053us      1           1   40.00 KB       10.00 MB  FINALIZE

    02:EXCHANGE         1      14m8s      14m8s      6           1          0              0  UNPARTITIONED

    01:AGGREGATE        6    2.746ms    5.205ms      6           1   67.00 KB       10.00 MB

    00:SCAN KUDU        6      2m33s      14m8s  6.10M          -1  299.00 KB              0  bms_ldgdb.ldg_690marketization_ledger t

    接下来我们来逐一提取和介绍上面Profile片段中的信息:

    1、表/列统计信息:

    Max Per-Host Resource Reservation: Memory=0B

    Per-Host Resource Estimates: Memory=20.00MB

    WARNING: The following tables are missing relevant table and/or column statistics.

    bms_ldgdb.ldg_690marketization_ledger

    前两行仅说明资源信息,它们不是很重要,也不经常使用。

    但是,下一行非常重要,因为Impala告诉我们是否检测到查询所涉及的表具有最新的统计信息,这一点非常关键,因为Impala使用表/列统计信息(table/column statistics information)来进行资源预估(resource estimation),并执行查询计划来确定运行查询的最佳策略,如果统计信息不是最新的,Impala最终将使用错误的查询计划,从而影响整体查询性能。

    在上面的示例中,我们可以看到bms_ldgdb.ldg_690marketization_ledger表缺少统计信息,Impala在查询计划中给出了警告来提示用户需要在该表上执行COMPUTE STATS来消除这个警告信息。关于表统计的更多信息,请参阅Table and Column Statistics(https://docs.cloudera.com/documentation/enterprise/latest/topics/impala_perf_stats.html)。

    2、查询计划详情:

    F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1

    |  Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B

    PLAN-ROOT SINK

    |  mem-estimate=0B mem-reservation=0B

    |

    03:AGGREGATE [FINALIZE]

    |  output: count:merge(*)

    |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    02:EXCHANGE [UNPARTITIONED]

    |  mem-estimate=0B mem-reservation=0B

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    F00:PLAN FRAGMENT [RANDOM] hosts=16 instances=16

    Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B

    01:AGGREGATE

    |  output: count(*)

    |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    00:SCAN KUDU [bms_ldgdb.ldg_690marketization_ledger t]

       predicates: industry_code != ''

       kudu predicates: is_delete = 0, ledger_status = 2, check_flag IN (4, -1), module IN (1, 2), account_date >= '2020-06-01'

       mem-estimate=0B mem-reservation=0B

       tuple-ids=0 row-size=15B cardinality=unavailable

    ----------------

    查询计划(Query plan)是Impala profile中最重要的部分之一,我们需要知道如何读取它,因为它告诉我们如何扫描(scan)表、交换数据(data exchange)和连接(join)以获得最终结果。

    如果查询很复杂,查询计划也可能会变得非常复杂,让我们从这个简单的查询开始,以了解它的基本信息。需要记住的一件事是,我们需要反向阅读这些信息,来理解Impala的执行计划。

    注意:执行计划是从下往下读的。

    2.1、KUDU 扫描:

    第一步从KUDU扫描(KUDU Scan)开始:

    00:SCAN KUDU [bms_ldgdb.ldg_690marketization_ledger t]

       predicates: industry_code != ''

       kudu predicates: is_delete = 0, ledger_status = 2, check_flag IN (4, -1), module IN (1, 2), account_date >= '2020-06-01'

       mem-estimate=0B mem-reservation=0B

       tuple-ids=0 row-size=15B cardinality=unavailable

    从上面的片段中我们可以获取下面这些有用的信息:

    运行查询所需的内存估计值为0,没有内存被预留

    补充:如果是HDFS扫描

    2.2、Aggregation操作:

    HDFS扫描完成后,Impala需要做聚合(Aggregation),因为我们的SQL语句中使用了COUNT(*):

    01:AGGREGATE

    |  output: count(*)

    |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    这里没有太多要解释的,这个步骤执行的是聚合操作。

    2.3、Fragment信息:

    F00:PLAN FRAGMENT [RANDOM] hosts=16 instances=16

    Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B

    00:SCAN KUDU和01:AGGREGATE片段上的SCAN和Aggregation操作都属于片段(FRAGMENT)F00,它在16个主机和16个实例上运行。F00这个片段ID可以用来在Profile的后面部分找到实际的片段统计信息,它可以告诉我们这个片段在运行时如何运行的详细信息。我们还将在本系列的后面部分讨论这个问题。

    2.4、Exchange操作:

    02:EXCHANGE [UNPARTITIONED]

    |  mem-estimate=0B mem-reservation=0B

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    在每个工作节点(worker node)上完成聚合之后,需要将每个工作节点的结果交换给协调器节点(coordinator),这个步骤主要做的是这个操作,之后,协调器节点需要对这些结果进行最后的汇总/合并(aggregation/merger):

    03:AGGREGATE [FINALIZE]

    |  output: count:merge(*)

    |  mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB

    |  tuple-ids=1 row-size=8B cardinality=1

    |

    以上两个操作都属于同一个片段01,该片段又可以用来引用Profile数据的其余部分,以获取关于查询的更详细的统计信息:

    F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1

    现在,让我们来看看Profile的执行概要部分:

    Operator       #Hosts   Avg Time   Max Time  #Rows  Est. #Rows   Peak Mem  Est. Peak Mem  Detail

    ----------------------------------------------------------------------------------------------------------------------------------

    03:AGGREGATE        1  316.053us  316.053us      1           1   40.00 KB       10.00 MB  FINALIZE

    02:EXCHANGE         1      14m8s      14m8s      6           1          0              0  UNPARTITIONED

    01:AGGREGATE        6    2.746ms    5.205ms      6           1   67.00 KB       10.00 MB

    00:SCAN KUDU        6      2m33s      14m8s  6.10M          -1  299.00 KB              0  bms_ldgdb.ldg_690marketization_ledger t

    在这里你可以找到这些有用的信息:

    1)每个操作花费的平均时间(Avg Time)和最大时间(Max Time):如果两者相差较大,我们就会知道每个worker节点运行作业时存在不平衡/倾斜(in-balance/skew)情况,从理论上讲,它们应该处理相同数量的数据,所有节点应该在相同的时间范围内完成任务

    2)实际行数和估计行数:#Row表示运行查询后实际返回的行数,Est. #Rows表示Impala根据表统计数据计算出的估计行数。如果#Row和Est. #Rows相差较大,就表明Impala中的表统计信息已经过时。在案例中,SCAN KUDU操作的Est. #Rows值为-1,#Rows的值为6.10M,就我们的测试表而言,我们没有表统计信息,因此Impala报告了-1的估算值。如果估计值(estimated value)是正数,但仍与实际返回的行数不同,我们就需要对该表运行COMPUTE STATS以更新统计信息

    3)参与查询操作的节点数量:#Hosts列告诉我们,有多少工作节点参与了查询中的相关操作。在我的例子中,由于数据很小,我们只有一个主机来运行查询

    4)实际内存和估计内存:Peak Mem和Est. Peak Mem是不言自明的,它们表示实际使用的内存与Impala根据表统计数据计算出的估计内存

    如果查询中有连接(join)操作,Profile的总结信息中还将向我们展示连接操作中使用了什么连接策略:广播连接(Broadcast Join)还是随机连接(Shuffle Join)。

    Processed: 0.009, SQL: 9