2011-04-29 64 views
1

简化我的问题,我有一组带有由双换行符分隔的“记录”的文本文件。像使用Hadoop将文本文件中的段落处理为单个记录

'多行文字'

'空行'

'多行文字'

'空行'

等等。

我需要分别转换每个多行单元,然后对它们执行mapreduce。

但是,我知道使用hadoop代码样板中的默认wordcount设置,以下函数中value变量的输入只是一行,并且不能保证输入与之前的输入连续线。

public void map(LongWritable key, Text value, 
       OutputCollector<Text, IntWritable> output, 
       Reporter reporter) throws IOException ; 

而且我需要它,输入value实际上是双新行的一个单元分隔的多行文字。

一些搜索变成了一个RecordReader类和一个getSplits方法,但没有简单的代码示例,我可以包裹我的头。

另一种解决方案是用多个空格字符替换多行文本中的所有换行符,并用它来完成。我宁愿不这样做,因为它有相当多的文本,并且在运行时方面很耗时。如果我这样做,我也必须修改很多代码,所以通过hadoop处理它对我来说最具吸引力。

回答

3

如果你的文件很小,那么它们不会被分割。基本上每个文件都是一个分配给一个映射器实例的分割。在这种情况下,我同意托马斯的观点。您可以通过串联字符串在您的映射器类中构建逻辑记录。您可以通过查找作为映射器值的空字符串来检测您的记录边界。

但是,如果文件很大并且分裂,那么除了实现您自己的文本输入格式类别外,我没有看到任何其他选项。您可以克隆现有的Hadoop LineRecordReader和LineReader java类。您必须对您的LineReader类的版本进行小改动,以便记录分隔符将为两行,而不是一行。一旦完成,您的映射程序将收到多行作为输入值。

+0

当我需要处理超过64MB的文件或者hadoop开始分割文件时,您的回复实际上会更有帮助。 – JasonMond 2011-06-17 03:26:54

1

它有什么问题?只要将前面的行写入StringBuilder并在达到新记录时刷新它。
当您使用文本文件时,它们不会被分割。对于这些情况,它使用FileInputFormat,它仅与可用文件的数量并行。

+0

谢谢!我花了一段时间才真正实施和测试,但你是对的。 – JasonMond 2011-05-20 01:31:26

相关问题