我有大量包含重复项的摄取设备数据。我还有一个单独的摄取元数据历史列表(用于唯一标识摄取的文件)。我希望使用历史记录对我摄取的设备数据进行重复数据删除。这个历史文件不小,因此我不打算将它加载到内存中。我也考虑过减少侧连接,但这将通过网络传递大量数据。
布隆过滤器是我正在寻找的东西,以减少我的历史文件的大小。但它给了我相反的结果,即它可能会报告我有一个副本,而我没有。
重复数据删除似乎是一个相当普遍的问题,我正在寻找其他人是否有可能的想法。
我有大量包含重复项的摄取设备数据。我还有一个单独的摄取元数据历史列表(用于唯一标识摄取的文件)。我希望使用历史记录对我摄取的设备数据进行重复数据删除。这个历史文件不小,因此我不打算将它加载到内存中。我也考虑过减少侧连接,但这将通过网络传递大量数据。
布隆过滤器是我正在寻找的东西,以减少我的历史文件的大小。但它给了我相反的结果,即它可能会报告我有一个副本,而我没有。
重复数据删除似乎是一个相当普遍的问题,我正在寻找其他人是否有可能的想法。
如果您打算使用 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());
}
不要忘记,如果您有大量重复项,那么组合器是减少网络流量的唯一最佳方法,足以使集群中的单个主机已经有许多重复项。