一、WordCount代码
package com.test5.scalaTest
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
object WordCount{
def main(args : Array[String]){
val conf = new SparkConf()//创建SparkConf对象
conf.setAppName("Wow,My First Spark Programe")//设置应用程序的名称,在程序运行的监控界面可以看到名称
conf.setMaster("local")//此时,程序在本地运行,不需要安装Spark集群
val sc = new SparkContext(conf)//创建SparkContext对象,通过传入SparkConf实例来定制Spark运行的具体参数和配置信息
val rdd= sc.textFile("E:\\data.txt",1)//读取本地文件并设置为一个Partion
val wordRDD = rdd.flatMap{line => line.split(" ")}//对每一行的字符串进行单词拆分并把所有行的拆分结果通过flat合并成为一个大的单词集合
val pairRDD = wordRDD.map{word => (word,1)}
var resultRDD = pairRDD.reduceByKey(_+_)//对相同的Key,进行Value的累计(包括Local和Reducer级别同时Reduce)
// cache算子,数据持久化,博客下面会有介绍
resultRDD = resultRDD.cache()
//action类算子触发执行 foreach算子是一个action算子
resultRDD.foreach(wordNumberPair => println(wordNumberPair._1 + " : " +wordNumberPair._2))//在命令行中打印该结果
//按照数量进行排序
// take(n) 将RDD中前n个元素拉回Driver端
resultRDD.map(x=>(x._2,x._1)).sortByKey(false).map(x=>(x._1,x._2)).take(10)
// sortBy可由程序员执行按照key来排序,还是按照value来排序
// first == take(1)
resultRDD.sortBy(x=>x._2,false).first()
sc.stop()//记得关闭创建的SparkContext对象
}
}
一般来说你的Application中有几个action类的算子,就会有几个job
因为RDD不存数据(里面存数据的位置),所以每次计算都要从HDFS里面读取,所以如果不持久化的话,每次都要计算三次
二、RDD的持久化(持久化的算子是一个懒执行算子)
cache:会将RDD的计算结果持久化到内存中
persist:会根据用户指定的持久化级别,将数据存储到不同的地方
注意点:
1、cache或者persist算子返回的结果必须赋值给一个变量,在接下来的job中直接使用这个变量那么就使用到了持久化的数据
2、持久化的算子后面不能立即紧跟action的算子,如下
val abc = rdd.cache().count()
持久化的算子是一个懒执行算子,需要有一个action算子触发执行,但是持久化的算子后面不能立即紧跟action的算子
在上图job0中实际上没有使用到持久化的数据,但是在接下来的job中(用了 resultRDD = resultRDD.cache()后)就可以使用到持久化的数据