gpt4 book ai didi

hadoop - Hive MAPJOIN作业将多少数据视为 “too large”?

转载 作者:行者123 更新时间:2023-12-02 21:27:58 25 4
gpt4 key购买 nike

编辑:添加了更多的文件大小详细信息,以及其他一些 session 信息。

我有一个看似简单的Hive JOIN查询,令人惊讶地需要几个小时才能运行。

SELECT a.value1, a.value2, b.value
FROM a
JOIN b ON a.key = b.key
WHERE a.keyPart BETWEEN b.startKeyPart AND B.endKeyPart;

我正在尝试确定执行时间对于我的数据集和AWS硬件选择而言是否正常,或者我只是试图加入太多数据。
  • 表A:〜220万行,压缩后的12MB,原始的81MB,4个文件。
  • 表B:〜245,000行,压缩6.7MB,原始14MB,一个文件。
  • AWS:emr-4.3.0,在大约5个m3.2xlarge EC2实例上运行。

  • 来自A的记录始终与B中的一个或多个记录匹配,因此从逻辑上我看到在使用WHERE子句修剪它们之前最多生成了5000亿行。

    为该作业分配了4个映射器,该映射器在 6小时中完成。这种查询和配置类型正常吗?如果没有,我应该怎么做才能改善它?

    我已经在JOIN键上对B进行了分区,它产生了5个分区,但是没有注意到明显的改进。

    此外,日志还显示,Hive优化器启动了本地 map 联接任务,大概是为了缓存或流式传输较小的表:
    2016-02-07 02:14:13 Starting to launch local task to process map join;  maximum memory = 932184064
    2016-02-07 02:14:16 Dump the side-table for tag: 1 with group count: 5 into file: file:/mnt/var/lib/hive/tmp/local-hadoop/hive_2016-02-07_02-14-08_435_7052168836302267808-1/-local-10003/HashTable-Stage-4/MapJoin-mapfile01--.hashtable
    2016-02-07 02:14:17 Uploaded 1 File to: file:/mnt/var/lib/hive/tmp/local-hadoop/hive_2016-02-07_02-14-08_435_7052168836302267808-1/-local-10003/HashTable-Stage-4/MapJoin-mapfile01--.hashtable (12059634 bytes)
    2016-02-07 02:14:17 End of local task; Time Taken: 3.71 sec.

    是什么导致这项工作进展缓慢?数据集看起来不会太大,并且“小表”大小恰好在“小表”限制(25MB)以下,该限制触发了MAPJOIN优化的禁用。

    EXPLAIN输出的转储为 copied on PasteBin以供引用。

    我的 session 启用输出和中间存储的压缩。这可能是罪魁祸首吗?
    SET hive.exec.compress.output=true;
    SET hive.exec.compress.intermediate=true;
    SET mapred.output.compress=true;
    SET mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
    SET io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;
    SET io.seqfile.compression.type=BLOCK;

    最佳答案

    我对这个问题的解决方案是完全在JOIN ON子句中表达JOIN谓词,因为这是在Hive中执行JOIN的最有效方法。至于为什么原始查询很慢,我认为映射器在逐行扫描中间数据集时需要100+十亿次的时间。

    由于Hive仅在JOIN ON子句中支持相等表达式,并且拒绝使用两个表别名作为参数的函数调用,因此无法将原始查询的BETWEEN子句重写为代数表达式。例如,以下表达式是非法的。

    -- Only handles exclusive BETWEEN
    JOIN b ON a.key = b.key
    AND sign(a.keyPart - b.startKeyPart) = 1.0 -- keyPart > startKeyPart
    AND sign(a.keyPart - b.endKeyPart) = -1.0 -- keyPart < endKeyPart

    最终,我修改了源数据,以将Hive startKeyPart数据类型中的 endKeyPartARRAY<BIGINT>之间的每个值都包括在内。
    CREATE TABLE LookupTable
    key BIGINT,
    startKeyPart BIGINT,
    endKeyPart BIGINT,
    keyParts ARRAY<BIGINT>;

    另外,我可以使用自定义Java方法在查询中内联生成此值; LongStream.rangeClosed()方法仅在Java 8中可用,而Java 8不属于AWS emr-4.3.0中的Hive 1.0.0。

    现在,我已经在数组中拥有了整个键空间,现在可以使用 LATERAL VIEWexplode()将数组转换为表,如下所示重写JOIN。
    WITH b AS
    (
    SELECT key, keyPart, value
    FROM LookupTable
    LATERAL VIEW explode(keyParts) keyPartsTable AS keyPart
    )
    SELECT a.value1, a.value2, b.value
    FROM a
    JOIN b ON a.key = b.key AND a.keyPart = b.keyPart;

    最终结果是,与相同硬件配置上的原始 6小时相比,上述查询大约需要 3分钟才能完成。

    关于hadoop - Hive MAPJOIN作业将多少数据视为 “too large”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35259593/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com