首页 > 解决方案 > 在大型 (50 GB) 数据集上没有 Partition BY 子句的 Hive 窗口函数 ROW_NUMBER 非常慢。有没有更好的优化方法?

问题描述

我有一个包含 5000 万条记录的 HDFS 文件,原始文件大小为 50 GB。

我正在尝试将其加载到配置单元表中,并在加载时使用以下内容为所有行创建唯一 ID。我正在使用 Hive 1.1.0-cdh5.16.1。

row_number() over(order by event_id, user_id, timestamp) as id

在执行时,我看到在 reduce 步骤中,分配了 40 个 reducer。39 个 reducer 的平均时间约为 2 分钟,而最后一个 reducer 大约需要 25 分钟,这显然让我相信大部分数据都是在一个 reducer 中处理的。

我怀疑 Order By 条款是这种行为的原因,并尝试了以下方法,

row_number() over() 作为 id

然而,我看到了同样的行为。

考虑 Map Reduce 范式,我觉得如果我们不指定 Partition BY 子句,数据必须在一个 reducer(非分布式)中处理,以便查看所有行并附加正确的行号。对于没有 partition By 子句或 partition By 偏斜列的任何 Window 函数,这可能是正确的。

现在,我的问题是,当我们不得不避免 Partition BY 子句时,我们如何规避这个问题并优化窗口功能?

标签: hadoophivemapreducequery-optimizationwindow-functions

解决方案


您可以使用 UUID:

select java_method('java.util.UUID','randomUUID')

在您的系统/工作流程中生成的 UUID 在其他系统中也将是唯一的,因为 UUID 是全局唯一的。UUID 完全分布式且快速运行。

同样在 Hive 3.x 中,您可以在 DDL 中使用SURROGATE_KEY函数


推荐阅读