我想知道实现 M/R 过滤器的最佳实践是什么,它将执行以下操作:
假设有一个键值对:
键:IntegerID,值:n 个整数值。例如:
1 | 1 2 2 3 3 0 6
2 | 0 3 4 5 6 7 8
3 | 1 5 2 6 2 2 6
我想过滤(排除)包含“0”的列
期望的输出:
1 | 2 2 3 3 6
2 | 3 4 5 6 8
3 | 5 2 6 2 6
谢谢
最佳答案
它看起来根本不像是 M/R 的最佳选择,因为 reducer 需要查看所有行的所有值才能做出关于列的“决定”。
我很想知道实际问题是什么,以及您最初决定使用 M/R 的原因。
如果我必须在 M/R 中执行此操作
我会让映射器将每一行分成一个 ([col#,rowkey],value) 对 - col# 是这样一列中的所有数据最终都会在一个缩减器中(谁可以决定是否放弃列或不)。 row_id 将用于将所有 reducer 的结果组合回一行。
例如,您示例中的第一行将从映射器发送到缩减器:
([0,1],1)
([1,1],2)
([2,1],2)
([3,1],3)
([4,1],3)
([5,1],0)
([6,1],6)
然后您需要一个分区器,它会根据列号(即 [col#,rowkey] 的第一个元素)对将映射输出分区到缩减器。还要编写一个自定义比较器,这样映射结果将到达按值排序的缩减器。
这样,reducer 只需要查看第一个值——如果它是 0,我们就知道该列包含 0,reducer 可以退出而不做任何其他事情。 如果它不是 0,它应该充当身份缩减器 - 只需按原样输出映射器的所有结果。
现在您需要第二个 M/R 作业以将其以原始格式重新组合在一起: 映射器不会做任何事情。 自定义分区器会将具有相同 rowkey 的所有结果发送到同一个 reducer。如果在最终结果集中保留行顺序很重要,则可以使用总顺序分区程序。 自定义比较器将按 rowkey 和 col# 对每个分区中的数据进行排序。
reducer 会将同一行的所有值一一写入一个字符串中,然后作为一行输出。
关于design-patterns - 过滤/排除 MapReduce 中的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23593932/