我试图reduceByKey
用java作为编程语言来理解Spark中的工作.
说我有句"我就是我自己".我将句子分成单词并将其存储为列表[I, am, who, I, am]
.
现在这个函数分配1
给每个单词:
JavaPairRDDones = words.mapToPair(new PairFunction () { @Override public Tuple2 call(String s) { return new Tuple2 (s, 1); } });
所以输出是这样的:
(I,1) (am,1) (who,1) (I,1) (am,1)
现在如果我有3个reducer运行,每个reducer将获得一个键和与该键相关的值:
reducer 1: (I,1) (I,1) reducer 2: (am,1) (am,1) reducer 3: (who,1)
我想知道
一个.在下面的函数中到底发生了什么.
湾 参数是什么new Function2
c.基本上是如何形成JavaPairRDD.
JavaPairRDDcounts = ones.reduceByKey(new Function2 () { @Override public Integer call(Integer i1, Integer i2) { return i1 + i2; } });
Sean Owen.. 6
我认为你的问题围绕着reduce函数,这是2个参数返回1的函数,而在Reducer中,你实现了多对多函数.
如果不那么通用,这个API会更简单.在这里,您提供了一个关联操作,可以将任何2个值减少到1(例如,两个整数总和为1).这用于将每个键的所有值减少到1.没有必要提供N对1功能,因为它可以通过2对1功能完成.在这里,您不能为一个键发出多个值.
结果是(键,减值)来自每个(键,值组).
经典Hadoop MapReduce中的Mapper和Reducer实际上都非常相似(只需要一个值集合而不是每个键的单个值)并让你实现很多模式.以一种浪费和复杂的方式,这种方式很好.
您仍然可以重现Mappers和Reducers的功能,但Spark中的方法是mapPartitions,可能与groupByKey配对.这些是您可能考虑的最常用的操作,我不是说您应该在Spark中以这种方式模拟MapReduce.事实上,它不太可能有效率.但这是可能的.
我认为你的问题围绕着reduce函数,这是2个参数返回1的函数,而在Reducer中,你实现了多对多函数.
如果不那么通用,这个API会更简单.在这里,您提供了一个关联操作,可以将任何2个值减少到1(例如,两个整数总和为1).这用于将每个键的所有值减少到1.没有必要提供N对1功能,因为它可以通过2对1功能完成.在这里,您不能为一个键发出多个值.
结果是(键,减值)来自每个(键,值组).
经典Hadoop MapReduce中的Mapper和Reducer实际上都非常相似(只需要一个值集合而不是每个键的单个值)并让你实现很多模式.以一种浪费和复杂的方式,这种方式很好.
您仍然可以重现Mappers和Reducers的功能,但Spark中的方法是mapPartitions,可能与groupByKey配对.这些是您可能考虑的最常用的操作,我不是说您应该在Spark中以这种方式模拟MapReduce.事实上,它不太可能有效率.但这是可能的.
reduceByKey的工作原理如下:
在RDD中,如果spark找到具有相同键的元素,则spark会获取其值并对这些值执行某些操作,并返回相同类型的值.例如,让我们采取,你有和RDD元素:
[k,V1],[K,V2],这里的V1,V2是相同的类型,然后新的Function2()的参数可以是3.
从第一个K,V对的值部分即V1.
从第二个K的值部分,V对即V2.
重写调用方法的返回类型,它同样是V1和V2类型(可以是作为调用方法一部分提供的函数操作的结果).
并注意,由于RDD是跨节点分布的,每个节点将执行自己的reduce操作,并将结果返回给master,并且master再次对worker的结果执行最终的reduce操作.
我猜这解释了你的疑问.