强制在配置单元中执行reduce阶段或第二个map reduce作业

roejwanj  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(292)

我正在运行以下表单的配置单元查询:

INSERT OVERWRITE LOCAL DIRECTORY ...
SELECT /*+ MAPJOIN(...) */ * FROM ...

因为 MAPJOIN ,结果不需要还原阶段。Map阶段使用大约5000名Map绘制人员,最终完成这项工作大约需要50分钟。结果发现,大部分时间都花在将这5000个文件复制到本地目录上。
为了优化这个,我替换了 SELECT * ...SELECT DISTINCT * ... (我事先知道我的结果已经是不同的,所以这实际上不会改变我的结果),以便强制执行第二个map reduce作业。第一个map reduce作业与以前相同,有5000个mapper和0个reducer。第二个map reduce作业现在有5000个mapper和3个reducer。通过此更改,现在只需要复制3个文件,而不是5000个,查询现在只需要大约20分钟。
因为我其实不需要 DISTINCT ,我想知道我的查询是否可以在不使用 DISTINCT ?

nnvyjq4y

nnvyjq4y1#

用另一个select或者一个无用的where子句 Package 查询,以确保它启动一个作业。

INSERT OVERWRITE LOCAL DIRECTORY ...
SELECT *
FROM (
    SELECT /*+ MAPJOIN(...) */ *
    FROM ..
) x
WHERE 1 = 1

明天有机会的时候我会运行这个,如果不起作用,我会删除答案的这一部分。如果你比我先到那就太好了。
另一种选择是利用文件名和行号的虚拟列强制不同的结果。这会使查询复杂化,并引入两个无意义的列,但其优点是您不必预先知道结果是不同的。如果你不能忍受那些无用的列,那就用另一个select来删除它们。

INSERT OVERWRITE LOCAL DIRECTORY ...
SELECT {{enumerate every column except the virutal columns}}
FROM (
    SELECT DISTINCT /*+ MAPJOIN(...) */ *, INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE 
    FROM ..
) x

这两种解决方案都比您提出的解决方案更加笨拙,但其优点是您不局限于具有不同结果的查询。
如果你不局限于Hive,我们还有另一个选择。你可以把这个 LOCAL 并将结果写入hdfs,即使有5000个Map器,hdfs也应该很快。然后使用 hadoop fs -getmerge /result/dir/on/hdfs/ 将结果拉入本地文件系统。不幸的是,这超出了配置单元,但是设置两步oozie工作流对于您的用例来说是可以接受的。

相关问题