在大型 (50 GB) 数据集上没有 Partition BY 子句的 Hive Window 函数 ROW_NUMBER 非常慢。有没有更好的优化方法?
Hive Window Function ROW_NUMBER without Partition BY Clause on a large (50 GB) dataset is very slow. Is there a better way to optimize?
我有一个包含 5000 万条记录的 HDFS 文件,原始文件大小为 50 GB。
我正在尝试将其加载到配置单元 table 中,并在加载时使用以下内容为所有行创建唯一 ID。我正在使用 Hive 1.1.0-cdh5.16.1.
row_number() 超过(按 event_id、user_id、时间戳排序)作为 id
在执行过程中,我看到在 reduce 步骤中分配了 40 个 reducer。 39 个 Reducer 的平均时间大约是 2 分钟,而最后一个 reducer 大约需要 25 分钟,这显然让我相信大部分数据都是在一个 reducer 中处理的。
我怀疑 Order By 子句是此行为的原因并尝试了以下操作,
row_number() over() as id
然而,我看到了相同的行为。
想到Map Reduce Paradigm,我觉得如果我们不指定Partition BY Clause,数据必须在一个reducer(非分布式)中处理才能看到所有行并附加正确的行号。对于没有分区依据子句或偏斜列分区依据的任何 Window 函数都是如此。
现在,我的问题是,当我们必须避免 Partition BY 子句时,我们如何规避这个问题并优化 window 函数?
您可以使用 UUID:
select java_method('java.util.UUID','randomUUID')
在您的 system/workflow 中生成的 UUID 在其他一些系统中也是唯一的,因为 UUID 是全局唯一的。 UUID 完全分布式且运行速度快。
在 Hive 3.x 中还有 SURROGATE_KEY 函数,您可以在 DDL
中使用它
而不是按 sort by
或 cluster by
排序
@leftjoin's 对于这个用例,建议非常有效(非常感谢!)。它不涉及 Reduce 步骤,工作在不到 3 分钟的时间内完成。我测试过,它确实产生了唯一的 ID。将检查底层代码,因为即使有 500 多个映射器,它也能够生成唯一的 ID,这非常有趣。
由于我使用的是 Hive 1.1,因此无法尝试 SURROGATE_KEY
很遗憾,@Strick's 建议没有用,但感谢分享。使用 Cluster By 不会产生唯一 ID。所有行都标记为 1,因为我的 cluster by 子句具有自然键。 Sort By 行为在结果和性能方面与 Order By 行为相似(32 分钟完成)。也许数据是通过一个缩减器汇集的,这意味着在这种情况下排序依据等同于排序依据。 (虽然我不确定)
仍在寻找 Window 可能没有 Partition By Clause 但应该分发的函数的解决方案
我有一个包含 5000 万条记录的 HDFS 文件,原始文件大小为 50 GB。
我正在尝试将其加载到配置单元 table 中,并在加载时使用以下内容为所有行创建唯一 ID。我正在使用 Hive 1.1.0-cdh5.16.1.
row_number() 超过(按 event_id、user_id、时间戳排序)作为 id
在执行过程中,我看到在 reduce 步骤中分配了 40 个 reducer。 39 个 Reducer 的平均时间大约是 2 分钟,而最后一个 reducer 大约需要 25 分钟,这显然让我相信大部分数据都是在一个 reducer 中处理的。
我怀疑 Order By 子句是此行为的原因并尝试了以下操作,
row_number() over() as id
然而,我看到了相同的行为。
想到Map Reduce Paradigm,我觉得如果我们不指定Partition BY Clause,数据必须在一个reducer(非分布式)中处理才能看到所有行并附加正确的行号。对于没有分区依据子句或偏斜列分区依据的任何 Window 函数都是如此。
现在,我的问题是,当我们必须避免 Partition BY 子句时,我们如何规避这个问题并优化 window 函数?
您可以使用 UUID:
select java_method('java.util.UUID','randomUUID')
在您的 system/workflow 中生成的 UUID 在其他一些系统中也是唯一的,因为 UUID 是全局唯一的。 UUID 完全分布式且运行速度快。
在 Hive 3.x 中还有 SURROGATE_KEY 函数,您可以在 DDL
中使用它而不是按 sort by
或 cluster by
@leftjoin's 对于这个用例,建议非常有效(非常感谢!)。它不涉及 Reduce 步骤,工作在不到 3 分钟的时间内完成。我测试过,它确实产生了唯一的 ID。将检查底层代码,因为即使有 500 多个映射器,它也能够生成唯一的 ID,这非常有趣。
由于我使用的是 Hive 1.1,因此无法尝试 SURROGATE_KEY
很遗憾,@Strick's 建议没有用,但感谢分享。使用 Cluster By 不会产生唯一 ID。所有行都标记为 1,因为我的 cluster by 子句具有自然键。 Sort By 行为在结果和性能方面与 Order By 行为相似(32 分钟完成)。也许数据是通过一个缩减器汇集的,这意味着在这种情况下排序依据等同于排序依据。 (虽然我不确定)
仍在寻找 Window 可能没有 Partition By Clause 但应该分发的函数的解决方案