简介:
我的文件块大小与HDFS块大小相同,每个块都是独立的,但必须全部提供给映射器。由于我的Mapper的setup
函数消耗了大量的时间,如何配置我的Mappers在丢弃之前处理多个块/块,同时还利用数据局部性?
长期:
我试图使用Hadoop来处理大块的大量大文件,而hadoop则非常出色。每个输入文件的每个块都可以完全分开处理,但每个块必须整体处理。为了在Hadoop下完成这项工作,我已经做到了这一点,以便每个块都与Hadoop块的大小完全相同。我开发了BlockInputFormat' BlockInputFormat'和' BlockRecordReader',一次将整个块交给Mapper。这似乎运作良好。
我面临的问题是,我的Mapper任务(必要时)需要在setup
方法中完成大量工作,然后才能执行地图'函数仅在整个对象被丢弃之前调用一次。我尝试通过mapreduce.input.fileinputformat.split.minsize
增加最小分割大小,这减少了设置调用的次数,这样我就可以在每个输入文件中调用一次设置(因为每个输入文件最终都在它自己的InputSplit中) )。我担心的是,在这样做的过程中,我将失去MapReduce提供的数据局部性的好处,因为我认为这意味着InputSplit跨越了Mapper机器上不一定必需的块。
总之,我的问题是:如何配置Mapper以读取多个块(甚至可能来自不同的输入文件),同时保留数据局部性?将每个块放入自己的文件中会更好吗?
感谢您提供的任何帮助, 菲尔
答案 0 :(得分:0)
根据块数或输入分割来分配Mapper。
使用CombineFileInputFormat()
将输入文件合并为一个拆分,以便一个映射器处理您的数据。
此外,您应设置max split size
属性,以防止Hadoop将整个输入合并为一个分割。
如果你正在处理不。 small
个文件然后它很好。
CombineFileInputFormat
并通过返回getRecordReader
实施CombineFileRecordReader
方法。 答案 1 :(得分:0)
使用MultipleInputFomat的addInputPath()方法将多个输入添加到一个映射器。
MultipleInputs.addInputPath(job,new Path(args [0]),TextInputFormat.class,YourMapper.class); MultipleInputs.addInputPath(job,new Path(args [1]),TextInputFormat.class,YourMapper.class);