目前我有
part-00001
part-00002
我知道使用hdfs -getmerge
是将这些文件合并为一个文件的最佳方式。但是,可以以编程方式吗?
我已尝试使用MultipleOutput,但它无效。我还尝试编写自己的CustomOutputFormat
,但由于多个reducer在将其并行写入文件时,在关闭Dataoutputstream时会出现org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException
错误。
答案 0 :(得分:2)
您始终可以使用java代码中的FileSystem class,并且可能只需要调用concat方法。
MultipleOutput几乎完全相反。它还生成自定义命名的文件,而不是拥有part-xxxxx
个文件,这通常意味着比以前更多的文件。
CustomOuputFormat也不是一个好主意,因为在任何情况下,您将拥有与reducer数量一样多的输出文件。输出格式不会改变。
使用单个reducer(setNumReduceTasks(1)
)可能是一个有效的解决方案,但不必要的昂贵,因为它“杀死”并行性(所有数据都由一个任务处理)。只有当您的数据相当小时才考虑使用它,否则请避免使用它。
另一个解决方案是在MapReduce作业完成后,简单地从你的java代码中调用hdfs -getmerge
作为shell命令。
答案 1 :(得分:0)
您无法以编程方式执行此操作,因为它由Hadoop管理并且创建这些文件取决于配置的reducer的数量。
为什么需要以编程方式合并这些文件?
如果输入作为另一个作业,您可以随时提及该目录作为输入,如果有许多小部件文件,则使用CombineInputFormat
。
否则hdfs -getmerge
是您想要合并自己的最佳选择。