我想知道实现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,因为减速机需要查看所有行的所有值才能对列做出"决定"。
我很想知道实际的问题是什么,以及为什么你们一开始决定采用M/R。
如果我有在M/R
中这样做我会让映射器将每一行分隔成([col#,rowkey],value)对- col#是这样,来自一列的所有数据将最终在一个reducer中(谁可以决定是否放弃列)。row_id将用于将来自所有reducer的结果组合回单行。
例如,你的例子中的第一行将从mapper发送到reducer,如下:
([0, 1], 1)
([1], 2)
((2, 1), 2)
((3,1), 3)
((4 1), 3)
(5, 1, 0)
((6,1), 6)
然后,您需要一个分区器,它将根据列号(即[col#,rowkey]的第一个元素)对映射输出分区到reducer。还要编写一个自定义比较器,这样映射结果将按值排序到达reducer。
这样,减速器只需要查看第一个值——如果它是0,我们知道该列包含一个0,减速器可以不做任何其他事情而退出。如果它不是0,它应该作为一个恒等减速器-只是输出所有的结果从映射器。
现在您需要第二个M/R作业将其恢复为原始格式:映射器不会做任何事情。自定义分区器将使用相同的rowkey将所有结果发送到相同的reducer。如果在最终结果集中保持行顺序很重要,则可以使用全顺序分区器。自定义比较器将按rowkey和col#对每个分区中的数据进行排序。
reducer将同一行的所有值逐一写入一个字符串,然后作为一行输出。