开发者学堂课程【大数据Spark2020最新课程(知识精讲与实战演练)第二阶段:RDD 算子_ Action _ reduce】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/689/detail/11980
RDD 算子_ Action _ reduce
内容介绍
一、前言
二、介绍 reduce
三、 reduce 的调用方式
四、小结
一、前言
在前面的学习中,我们已经了解了很多有关转换的操作了,转换操作的算子有一个共同的特性,它们都是惰性的,即在执行算法时,并不会真的去调度运行,求得结果,而是只生成了对应的 RDD ,只有在 Action 操作的时候,才会运行并求得结果。目前我们对 Action 的了解只有一个算子,就是 collect 。
collect 的作用是把数据从最终的 RDD 当中提取出来,可以说它的操作是十分简单的,但他并不能适用于所有的场景,无法用于求整个集合的聚合,也无法求得最大值或数量。
二、介绍 reduce
接下来我们通过 Action 操作了解一下 Spark 的多种求结果的方法。第一个 Action 操作算子叫做 reduce ,它与 reduceByKey 的区别在于它们一个是动作算子,一个是转换算子,这是它们的本质区别。它们还有其他的区别,我们用一个事例来说明一下。
假设一个 RDD 里面有1万条数据数据,大部分 Key 是相同的,有10个不相同的,如果在这个 RDD 中调用 reduceByKey ,会生成10条数据。 reduceByKey 先按照 Key 进行分组,然后对每一组的数据求 reduce ,所以会有10组数据,最终也会生成10组结果。如果在 RDD 上调用 reduce,这个过程就是 reduce 调用 reduce ,就只会生成一条数据,这是它们最大的区别。
总的来说, reduceByKey 本质上是先按照 Key 分组,然后把每组聚合; reduce 是针对于一整个数据集来进行聚合。还有一个区别就是,reduceByKey 是针对 KV 型数据来进行计算的, reduce 是针对所有类型的数据进行计算。
Reduce 操作是一个 Action ,它会作用于 RDD 的每一个分区,会先在每一个分区中reduce 出一个结果,然后 reduce 出一个结果,最终汇总到 Driver 上进行计算。 Driver 是客户端的核心,是运行方法的总控和 Spark 的驱动。这个流程与 Shuffle 操作并不一样,因此它不是 Shuffle 操作(如图所示)。
简单总结一下, Shuffle 操作分为mapper 端和 reducer 端,
mapper将数据放入 partition 函数中计算,求得分往哪个
reducer ,后分到对应的 reducer 中,有点类似图片上的内容(上图)。
对于 reduce 操作来说,它没有mapper 和 reducer ,因为 reduce
算子会作用于 RDD 中的每一个分区,在分区上求得局部结果后,最终
汇总到 Driver 中,求得最终结果。
所以 reduce 并不是一个Shuffle 操作。在前面的内容中有提到,
RDD 有五大属性,其中有一个属性叫做 partition ,用于 keyValue
型数据分组,在 Shuffle 过程中使用,同时只有KV 型数据才能进行
Shuffle 操作。
三、 Reduce 的调用方式
可以看到的是, reduce 的调用方式与 reduceByKey 是一模一样的,它也接收一个函数,这个函数有两个参数,一个叫做 currValue ,一个叫做 agg ,结果是一个 T 类型。
首先要明确一下需求,即统计整个数据集当中所有商品的总价,最终得到("结果", price)的结果。然后复制数据集,开始写 reduce 代码。进入idea 当中创建新的 class ,叫做 ActionOp 。然后创建方法 Test ,导入数据集。
接下来的流程是拷贝 sc ,打开transformationOp ,复制 sc 的定义。然后对 Seq 求 reduce 。 reduce 传入的函数会接收两个参数, curr 和 agg ,最终进行计算。
如果是 reduceByKey 算子,curr 就已经按照 Key 分组过了,所以这里的 curr 只是 Value 的类型,对应整条数据。这里的 agg 是局部汇总结果,由结果( result )类型确定。
result 是一个源组,是最终生成的总和源组,直接打印源组,然后运行代码,得出结果为(总价,45)。
代码如下:
@Test
def reduce() : Unit = {
val rdd = sc.parallelize(Seq(("
手机",10.0),("手机",15.0),("电脑",20.0)))
val result: (String,Double) = rdd.reduce((curr,agg) => ("
总价",curr._2 +agg._2))
println(result)
}
四、小结
reduce 需要注意的几个点,简单总结一下,第一点,函数中传入的 curr
参数并不是 Value ,而是一整条数据。
第二点, reduce 整体上的结果只有一个,它只产生一个结果。以上就
是 reduce 的相关内容。