3

我有大量包含重复项的摄取设备数据。我还有一个单独的摄取元数据历史列表(用于唯一标识摄取的文件)。我希望使用历史记录对我摄取的设备数据进行重复数据删除。这个历史文件不小,因此我不打算将它加载到内存中。我也考虑过减少侧连接,但这将通过网络传递大量数据。

布隆过滤器是我正在寻找的东西,以减少我的历史文件的大小。但它给了我相反的结果,即它可能会报告我有一个副本,而我没有。

重复数据删除似乎是一个相当普遍的问题,我正在寻找其他人是否有可能的想法。

4

2 回答 2

4

如果您打算使用 Map/Reduce 进行重复数据删除,并且您希望使用多台机器来完成该任务,则您必须通过网络发送所有数据。这就是 Hadoop 所做的!

当然你也可以在一台机器上运行所有的东西,只是需要更长的时间。在它的核心,重复数据删除是 Hadoop 自然地做的事情之一,您可以免费获得大部分功能:Hadoop 在 Map 步骤中散列您的所有“键”,并确保属于“键”的所有“值”最终都在同一个减速机。

任务本身相当简单,实际上它与WordCount示例(最简单的 Map/Reduce 作业之一)几乎相同。只需跳过输出计数并仅输出键(使用NullWritable作为值)。我在下面包含了 map 和 reduce 函数。注意:如果您为 Reducer 使用 N 多台机器,则需要连接每个 Reducer 生成的 N 个输出文件以返回单个文件。这是代码:

public void map(LongWritable key, Text value, Context context) 
  throws IOException, InterruptedException {
     String line = value.toString(); //process your data here
     context.write(line, NullWritable.get());
 }


public void reduce(Text key, Iterable<IntWritable> values, Context context) 
  throws IOException, InterruptedException {
     context.write(key, NullWritable.get());
 }

编辑1:如果您想按照其他答案的建议使用组合器,您可以很容易地做到这一点。在通过网络发送数据之前运行组合器,您可以将其视为本地化简器。刚设置

job.setCombinerClass(Reduce.class);

其中 Reduce 是包含 reduce() 方法的类。


编辑2:根据我收到的建议:value.toString()如果您只有字符串要处理并且根本不需要进行任何处理,那么这是多余的并且不需要。然后你可以简化Mapper一点:

public void map(LongWritable key, Text value, Context context) 
  throws IOException, InterruptedException {
     context.write(value, NullWritable.get());
 }
于 2013-10-16T21:42:45.727 回答
1

不要忘记,如果您有大量重复项,那么组合器是减少网络流量的唯一最佳方法,足以使集群中的单个主机已经有许多重复项。

于 2013-10-16T21:59:30.323 回答