Spark-Core算子

算子分类

1)Transformation 变换/转换算子:这种变换并不触发提交作业,完成作业中间过程处理。
Transformation 操作是延迟计算的,也就是说从一个RDD 转换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触发运算。

2)Action 行动算子:这类算子会触发 SparkContext 提交 Job 作业。
Action 算子会触发 Spark 提交作业(Job),并将数据输出 Spark系统。

1.输入:在Spark程序运行中,数据从外部数据空间(如分布式存储:textFile读取HDFS等,parallelize方法输入Scala集合或数据)输入Spark,数据进入Spark运行时数据空间,转化为Spark中的数据块,通过BlockManager进行管理。
2.运行:在Spark数据输入形成RDD后便可以通过变换算子,如filter等,对数据进行操作并将RDD转化为新的RDD,通过Action算子,触发Spark提交作业。 如果数据需要复用,可以通过Cache算子,将数据缓存到内存。
3.输出:程序运行结束数据会输出Spark运行时空间,存储到分布式存储中(如saveAsTextFile输出到HDFS),或Scala数据或集合中(collect输出到Scala集合,count返回Scala int型数据)。

transformation 操作

filter()
map()
sample()
union()
groupbykey()
sortbykey()
combineByKey()
subtractByKey()
mapValues()
Keys()
Values()

action操作

collect()
count()
first()
countbykey()
saveAsTextFile()
reduce()
take(n)
countBykey()
collectAsMap()
lookup(key)

数据文件路径:./data/log

2019-04-08 11:59:26 INFO [http-bio-8101-exec-136]
2019-04-08 11:59:43 INFO [http-bio-8101-exec-1]
2019-04-08 11:59:51 INFO [http-bio-8101-exec-186]
2019-04-08 11:59:51 INFO [http-bio-8101-exec-107]
2019-04-08 11:58:39 INFO [http-bio-8101-exec-151]
2019-04-08 11:58:48 INFO [http-bio-8101-exec-151]
2019-04-08 11:59:01 INFO [http-bio-8101-exec-124]
2019-04-08 11:59:13 INFO [http-bio-8101-exec-1]
2019-04-08 11:59:29 INFO [http-bio-8101-exec-21]
2019-04-08 11:59:37 INFO [http-bio-8101-exec-79]
2019-04-08 11:58:39 INFO [http-bio-8101-exec-9]
2019-04-08 11:59:30 INFO [http-bio-8101-exec-154]

读取数据

var input = "./data/log"
    val spark: SparkSession = SparkSession.builder()
      .appName("spark_job")
      .getOrCreate()
    val logRDD: RDD[String] = spark.read.textFile(input).rdd

map的输入变换函数应用于RDD中所有元素

var logArray = logRDD.map(line => {
      var arr: Array[String] = line.split(" ")
      (arr.apply(0)+","+arr.apply(1)+","+arr.apply(3));
    }
    );

输出:
2019-04-08,11:59:26,INFO
2019-04-08,11:59:43,INFO
2019-04-08,11:59:51,INFO
2019-04-08,11:58:39,INFO
2019-04-08,11:58:48,INFO
2019-04-08,11:59:01,INFO
2019-04-08,11:59:13,INFO
2019-04-08,11:59:29,INFO
2019-04-08,11:59:37,INFO
2019-04-08,11:59:30,INFO
2019-04-08,11:59:45,INFO

filter过滤操作,满足filter内function函数为true的RDD内所有元素组成一个新的数据集

var filter_rdd = logArray.filter(line => {
       line.contains("2019-04-08,11:59:29");
     });
    filter_rdd.foreach(println(_));

输出结果:
2019-04-08,11:59:29,INFO
2019-04-08,11:59:29,INFO

distinct,返回一个在源数据集去重之后的新数据集,即去重

    var dis_rdd = logArray.take(20).distinct;
    dis_rdd.foreach(println(_));

输出结果:
2019-04-08,11:59:26,INFO
2019-04-08,11:59:43,INFO
2019-04-08,11:59:51,INFO
2019-04-08,11:58:39,INFO
2019-04-08,11:58:48,INFO
2019-04-08,11:59:01,INFO

groupByKey,在一个PairRDD或(k,v)RDD上调用,返回一个(k,Iterable)

    var pair_rdd = logArray.map(line => {
      (line,1)
    })
    pair_rdd.groupByKey().collect.foreach(println(_))

输出结果:
(2019-04-08,12:15:00,INFO,CompactBuffer(1))
(2019-04-08,12:50:52,INFO,CompactBuffer(1, 1))
(2019-04-08,12:12:51,INFO,CompactBuffer(1))
(2019-04-08,12:19:32,INFO,CompactBuffer(1))
(2019-04-08,12:19:06,INFO,CompactBuffer(1))
(2019-04-08,12:14:54,INFO,CompactBuffer(1))
(2019-04-08,12:16:21,INFO,CompactBuffer(1))
(2019-04-08,12:20:07,INFO,CompactBuffer(1, 1))

    //先对key分组,后对value 排序
    var pair_rdd2 = logArray.map(line => {
      var arr: Array[String] = line.split(",")
      (arr.apply(0),arr.apply(1))
    }).groupByKey.map(line => {
      val key = line._1
      val value = line._2
      (key,value.toList.sorted)
    }).collect().foreach(println(_))

输出结果:
(2019-04-08,List(11:58:39, 11:58:39, 11:58:42, 11:58:46, 11:58:47, 11:58:48, 11:58:50, 11:58:56, 11:59:00, 11:59:01, 11:59:01)

reduceByKey,是对相同key的数据进行处理,最终每个key只保留一条记


  var pair_rdd3 = logArray.map(line => {
      var arr: Array[String] = line.split(",")
      (arr.apply(0),arr.apply(1))
    }).reduceByKey((v1,v2) => {
      v1 + ";" + v2
    }).collect().foreach(println(_))

输出结果:

(2019-04-08,11:59:26;11:59:43;11:59:51;11:59:51;11:58:39;11:58:48;11:59:01;11:59:13;11:59:29;11:59:37;11:58:39;11:59:30;11:59:45)

注意:
使用reduceByKey()的时候,本地的数据先进行merge然后再传输到不同节点再进行merge,最终得到最终结果。
而使用groupByKey()的时候,并不进行本地的merge,全部数据传出,得到全部数据后才会进行聚合成一个sequence,groupByKey()传输速度明显慢于reduceByKey()。

countByKey用于统计RDD[K,V]中每个K的数量,返回具有每个key的计数的(k,int)pairs的hashMap

    println(pair_rdd.countByKey())

输出结果:
Map(2019-04-08,12:11:26,INFO -> 1, 2019-04-08,12:25:48,INFO -> 1, 2019-04-08,12:14:03,INFO -> 1, 2019-04-08,12:47:42,INFO -> 1)

collect将一个RDD以一个Array数组形式返回其中的所有元素。

    pair_rdd.collect.foreach(println(_))

sortByKey 同样是基于pairRDD的,根据key值来进行排序。

    pair_rdd.sortByKey().collect().foreach(println(_))

输出结果:
(2019-04-08,11:59:26,INFO,1)
(2019-04-08,11:59:43,INFO,1)
(2019-04-08,11:59:51,INFO,1)
(2019-04-08,11:59:51,INFO,1)
(2019-04-08,11:58:39,INFO,1)
(2019-04-08,11:58:48,INFO,1)
(2019-04-08,11:59:01,INFO,1)

saveAsTextFile(path) 将dataSet中元素以文本文件的形式写入本地文件系统或者HDFS

    logArray.saveAsTextFile("/home/xxx/xxx/")    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值