Spark常用算子的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lzxlfly/article/details/86440175

1、map&flatMap


要输入的源文件word.txt如下

spark hbase
slor
hive kylin flink

map(func)

 map函数会对每一条输入进行指定的操作,然后为每一条输入返回一个对象;map返回的数据对象的个数和原来的输入数据是相同的

val lineRdd = sc.textFile("./word.txt");
val mapRdd=lineRdd.map(f=>f.split("\\s")).foreach(x => println(x.toList));

 返回的是Array[String]的RDD

List(spark, hbase)
List(slor)
List(hive, kylin, flink)

flatMap(func)

flatMap函数则是两个操作的集合——正是“先映射后扁平化”:同map函数一样:对每一条输入进行指定的操作,然后为每一条输入返回一个对象;最后将所有对象合并为一个对象;flatMap返回的个数则是不同的

val lineRdd = sc.textFile("./word.txt");
val mapRdd2=lineRdd.flatMap(f=>f.split("\\s+")).collect();
println(mapRdd2.toList)

 返回的是String类型的RDD

List(spark, hbase, slor, hive, kylin, flink)

flatMap结合了map和flatten的功能,相当于如下操作

val mapRdd=lineRdd.map(f=>f.split("\\s+")).collect()
println("--------map--------")
mapRdd.foreach(f=>println(f.toList))
println("--------flat--------")
println(mapRdd.flatten.toList)

 输出如下

--------map--------
List(spark, hbase)
List(slor)
List(hive, kylin, flink)
--------flat--------
List(spark, hbase, slor, hive, kylin, flink)

2、map&mapPartitions

两者操作粒度不同:map是对rdd中的每一个元素进行操作;mapPartitions则是对rdd中的每个分区的迭代器进行操作

  假设一个rdd有6个元素,分成2个分区。如果使用map方法,map中的输入函数会被调用6次;而使用mapPartitions方法的话,其输入函数会只会被调用2次,每个分区调用1次。

      val paralleRdd = sc.parallelize(1 to 6,2)
      
      def funcPerElement(e:Int):Int = {
           println("e="+e)
           e*2
      }
      
      def funcPerPartition ( iter : Iterator [Int] ) : Iterator [Int] = {
         println("iter="+iter)
         var res = for (e <- iter ) yield e
         res
      }
      
        paralleRdd.map(funcPerElement).collect()
        paralleRdd.mapPartitions(funcPerPartition).collect()
map--e=1
map--e=2
map--e=3
map--e=4
map--e=5
map--e=6

mapPartitions--iter=non-empty iterator
mapPartitions--iter=non-empty iterator

两者初始化连接次数不同:在上面的例子中,mapPartitons只需初始化2个次,每个分区一次;而map要初始化6次,每个元素一次。显然在大量数据下mapPartitons的开销小,节省集群资源,便于进行批处理操作。
 

3、reduce&reduceByKey

reduce(func)

reduce 是一种聚合函数,接收两个参数,并返回一个参数,循环操作,直到最后剩下一个参数。用于数据交换和结合,聚合数据集与一体。

val paralleRdd = sc.parallelize(1 to 10)
val sum=paralleRdd.reduce((x, y) => x + y)
println(sum)
55

reduceByKey(func)

对一对(k,v)类型的数据集调用时,返回一个(k,v)对的数据集。对每个k的v用给定的reduce函数func聚合,该函数的类型必须为(v,v)=>v,对k相同的v操作得到新v。也即k相同的多个元素的v被reduce为一个值,然后与原RDD中的k组成一个新的kv对。如下示例:

val paralleRdd = sc.parallelize(List((1,2),(1,3),(2,5),(2,6),(3,7)))
val reduceRdd = paralleRdd.reduceByKey((x,y) => x + y).collect()
println(reduceRdd.toList)

 对k相同的v进行累加操作, 得到新的k,v

List((1,5), (3,7), (2,11))

 

参考:http://spark.apache.org/docs/2.2.2/rdd-programming-guide.html#working-with-key-value-pairs

猜你喜欢

转载自blog.csdn.net/lzxlfly/article/details/86440175