将50个大文件中的列/字段合并为一个文件

时间:2015-08-08 14:24:31

标签: hadoop hive apache-pig

我想知道组合所有字段/列的有效方法 将多个文件合并为一个文件。每个

File1中:

1,fname1,one
2,fname2,two

文件2:

1,lname1,lone
2,lname2,ltwo

预期输出

1,fname1, one,lname1,lone
2,fname2,two,lname2,ltwo

我有大约70个这样的文件,每个记录超过100米,每列6个。

目前我正在尝试使用hive join执行此操作。它似乎永远在运行 - 差不多24小时仍在运行。我需要一个更好的解决方案。

2 个答案:

答案 0 :(得分:1)

以“天真”的方式加入70个文件意味着Hive必须按顺序执行69个JOIN步骤,左侧数据集越来越大。 如果你使用嵌套的子查询明确地分解任务 - 即将A与B连接,C与D连接,然后将AB与CD连接等 - 它将不那么具有灾难性,但仍然是资源密集型。

在任何情况下,Hive都不会利用所有文件已经排序的事实(请参阅有关Sort-Merge连接的文档和关于bucketization的明确要求)

实际上,您的问题与大型机上的COBOL一样久远。而且我不确定它是否能够以分布式方式有效地解决(需要将文件一致地分区开始)。所以请考虑非Hadoop解决方案:

  • 如果您想要性能和工业级解决方案 - 和 有大量的现金可用 - 然后购买SyncSort的许可证或 类似的工具
  • 如果您只想立即完成工作,请下载所有文件 到Linux机器盒并尝试旧的sort -m命令(不确定 但是,对RAM和交换的影响

答案 1 :(得分:0)

拿2:而不是多个JOIN,那么创建一个巨大的“稀疏”表然后运行一个庞大的GROUP BY呢?

  • 创建一个包含所有预期101列的临时表
  • 创建50个EXTERNAL表,映射到50个源文件(50个不同的目录),每个3列,当然
  • 运行50个INSERT - SELECT查询,将每个文件加载到临时表中,在适当的列中,即

insert into table SPARSE select ID, CODE1, VAL1, null, null, null, ... from SOURCE1 ; insert into table SPARSE select ID, null, null, CODE2, VAL2, null, ... from SOURCE2 ;

  • 运行最后的GROUP BY以展平结果:对于给定的ID,CODE1只有一个非Null值,因此Max(CODE1)实际上意味着“获取来自SOURCE1的值和忽略来自其他来源的Nulls“

select ID, Max(CODE1), Max(VAL1), Max(CODE2), ... from SPARSE group by ID

我不是百分百肯定它可以超过你当前24小时的处理时间;但它可能值得一试。希望单个大规模的MapReduce作业比分布式JOIN的多个作业更有效。

~~~~

顺便说一下,庞大的GROUP BY可能需要仔细调整,即检查Mappers&的数量。减速器是有意义的(如果没有,尝试在临时表上运行统计信息和/或硬设置某些属性),确保使用Snappy或LZ4压缩中间结果(以减少I / O占用空间和合理的CPU开销)等。通常的东西。

一个主要的优化可能涉及临时表上的存储桶;但是你不能对一个bucketized表运行多个INSERT,所以你必须尝试一个大量的INSERT OVERWRITE - SELECT UNION ALL SELECT UNION ALL ... yuck。