正如标题所说,我有一个关于map-reduce的任务设计:
想了想只需要将部分数据(可能是10%的数据)送入reducer,剩下的数据直接输出到HDFS即可。然后最后,我只是将这两个来自 mapper 和 reducer 的输出文件结合起来(我必须得到一个关于这个总数据的统一文件或目录)。我认为,这样做可以降低此任务运行的带宽成本。
那么我的想法能实现吗?(我知道如何直接从mapper输出到HDFS,但这需要mapper既输出到HDFS又发送数据到reducer)
正如标题所说,我有一个关于map-reduce的任务设计:
想了想只需要将部分数据(可能是10%的数据)送入reducer,剩下的数据直接输出到HDFS即可。然后最后,我只是将这两个来自 mapper 和 reducer 的输出文件结合起来(我必须得到一个关于这个总数据的统一文件或目录)。我认为,这样做可以降低此任务运行的带宽成本。
那么我的想法能实现吗?(我知道如何直接从mapper输出到HDFS,但这需要mapper既输出到HDFS又发送数据到reducer)
一种解决方案是对 90% 的文件使用MultipleOutputs 的 write() 方法,剩下的 10% 可以使用context.write()
映射器中的法线,这样,它们只进入减速器。
可以使用 MultipOutputs 中的此功能 -
void write(K key, V value, String baseOutputPath);
第二种解决方案是直接为 Mapper 使用FileSystem(来自 Hadoop Api),将 90% 的文件输出到 HDFS。但是我不知道如果你运行很多映射器会有多高效。上面的 MultipleOutput 也是如此 -
就像是:
在映射器的setup()函数中执行此操作 -
FileSystem fs = file.getFileSystem(context.getConfiguration());
FSDataOutputStream fileOut = fs.create(new Path("your_hdfs_filename"));
在map()函数内部执行此操作 -
create()函数会返回一个 FSDataOutputStream 对象。使用write( ) 函数写入文件。
完成后在cleanup()函数中关闭 FileSystem 对象。就像是 -fs.close();