Spark代码流程
1. 创建SparkConf对象。
-- 可以设置Application name。
--可以设置运行模式及资源需求。
2. 创建SparkContext对象。
3. 基于Spark的上下文创建一个RDD,对RDD进行处理。
4. 应用程序中要有Action类算子来触发Transformation类算子执行。
5.关闭Spark上下文对象SparkContext。
SparkRdd的创建方式
基于sparkContext对象创建
1)从Hadoop文件系统(如HDFS、Hive、HBase)输入创建。
2)从父RDD转换得到新RDD。
3)通过parallelize或makeRDD将单机数据创建为分布式RDD。
4)基于DB(Mysql)、NoSQL(HBase)、S3(SC3)、数据流创建。
从集合创建RDD
parallelize
def parallelize[T](seq: Seq[T], numSlices: Int = defaultParallelism)(implicit arg0: ClassTag[T]): RDD[T]
从一个Seq集合创建RDD。
参数1:Seq集合,必须。
参数2:分区数,默认为该Application分配到的资源的CPU核数
[java] view plain copy
scala> var rdd = sc.parallelize(1 to 10)
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[2] at parallelize at :21
scala> rdd.collect
res3: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> rdd.partitions.size
res4: Int = 15
//设置RDD为3个分区
scala> var rdd2 = sc.parallelize(1 to 10,3)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[3] at parallelize at :21
scala> rdd2.collect
res5: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> rdd2.partitions.size
res6: Int = 3
makeRDD
def makeRDD[T](seq: Seq[T], numSlices: Int = defaultParallelism)(implicit arg0: ClassTag[T]): RDD[T]
这种用法和parallelize完全相同
def makeRDD[T](seq: Seq[(T, Seq[String])])(implicit arg0: ClassTag[T]): RDD[T]
该用法可以指定每一个分区的preferredLocations。
[java] view plain copy
scala> var collect = Seq((1 to 10,Seq("slave007.lxw1234.com","slave002.lxw1234.com")),
(11 to 15,Seq("slave013.lxw1234.com","slave015.lxw1234.com")))
collect: Seq[(scala.collection.immutable.Range.Inclusive, Seq[String])] = List((Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
List(slave007.lxw1234.com, slave002.lxw1234.com)), (Range(11, 12, 13, 14, 15),List(slave013.lxw1234.com, slave015.lxw1234.com)))
scala> var rdd = sc.makeRDD(collect)
rdd: org.apache.spark.rdd.RDD[scala.collection.immutable.Range.Inclusive] = ParallelCollectionRDD[6] at makeRDD at :23
scala> rdd.partitions.size
res33: Int = 2
scala> rdd.preferredLocations(rdd.partitions(0))
res34: Seq[String] = List(slave007.lxw1234.com, slave002.lxw1234.com)
scala> rdd.preferredLocations(rdd.partitions(1))
res35: Seq[String] = List(slave013.lxw1234.com, slave015.lxw1234.com)
指定分区的优先位置,对后续的调度优化有帮助。
从外部存储创建RDD
textFile
//从hdfs文件创建.
[java] view plain copy
//从hdfs文件创建
scala> var rdd = sc.textFile("hdfs:///tmp/lxw1234/1.txt")
rdd: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[26] at textFile at :21
scala> rdd.count
res48: Long = 4
//从本地文件创建
scala> var rdd = sc.textFile("file:///etc/hadoop/conf/core-site.xml")
rdd: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[28] at textFile at :21
scala> rdd.count
res49: Long = 97
注意这里的本地文件路径需要在Driver和Executor端存在。
从其他HDFS文件格式创建
hadoopFile
sequenceFile
objectFile
newAPIHadoopFile
从Hadoop接口API创建
hadoopRDD
newAPIHadoopRDD
比如:从HBase创建RDD
[java] view plain copy
scala> import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor, TableName}
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor, TableName}
scala> import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
scala> import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.client.HBaseAdmin
scala> val conf = HBaseConfiguration.create()
scala> conf.set(TableInputFormat.INPUT_TABLE,"lxw1234")
scala> var hbaseRDD = sc.newAPIHadoopRDD(
conf,classOf[org.apache.hadoop.hbase.mapreduce.TableInputFormat],classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],classOf[org.apache.hadoop.hbase.client.Result])
scala> hbaseRDD.count
res52: Long = 1
Action类算子和Transformation类算子
Transformations转换算子
概念:
Transformations类算子是一类算子(函数)叫做转换算子,如map,flatMap,reduceByKey等。Transformations算子是延迟执行,也叫懒加载执行。
也就是说从一个RDD 转换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触发运算。
* spark转换算子
* 1、filter
参数是函数,函数会过滤掉不符合条件的元素,返回值是新的RDD。
* 2、sample
随机抽样算子,根据传进去的小数按比例进行又放回或者无放回的抽样。
* 3、map
在Map中,我们会传入一个函数,该函数对每个输入都会返回一个数组(或者元组、集合)(而不是一个元素)。
* 4、flatMap
是map的一种扩展。在flatMap中,我们会传入一个函数,该函数对每个输入都会返回一个数组或者元组、集合(而不是一个元素),然后,flatMap 把生成的多个集合(数组)“拍扁”成为一个集合(数组)或者字符串RDD。
* 5、reduceByKey
将K、V格式的Rdd中相同的Key根据相应的逻辑进行处理。 如:单词统计的加法操作。
* 6、distinct
没有参数,将RDD里的元素进行去重操作。
* 7、intersection
参数是RDD,求出两个RDD的共同元素。
* 8、subtract()
参数是RDD,将原RDD里和参数RDD里相同的元素去掉 即:返回的数据是原RDD中不和参数RDD中相同的元素。
* 9、cartesian
参数是RDD,求两个RDD的笛卡儿积。
* 10、sortByKey
作用在K,V格式的RDD上,对key进行升序或者降序排序.
* 11、 mapPartiiton:
与map类似,遍历的单位是每个partition上的数据。
Spark中Key-Value型转换算子
* 1、join
内连接join;相当于SQL中的内关联join,只返回两个RDD根据K可以关联上的结果,join只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
* 2、leftOuterJoin
类似于SQL中的左外关联left outer join,返回结果以前面的RDD为主,关联不上的记录为空。只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
* 3、rightOuterJoin
类似于SQL中的有外关联right outer join,返回结果以参数中的RDD为主,关联不上的记录为空。只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
* 4、cogroup
当调用类型(K,V)和(K,W)的数据上时,返回一个数据集(K,(Iterable
* 5、zip
将两个RDD中的元素(KV格式/非KV格式)变成一个KV格式的RDD,两个RDD的个数必须相同。
* 6、zipWithIndex
该函数将RDD中的元素和这个元素在RDD中的索引号(从0开始)组合成(K,V)对
Action行动算子
概念:
Action类算子也是一类算子(函数)叫做行动算子,如foreach,collect,count等。Transformations类算子是延迟执行,Action类算子是触发执行。一个application应用程序中有几个Action类算子执行,就有几个job运行。
Action类算子
count
返回原RDD中数据的个数。
take(n)
返回一个包含数据集前n个元素的集合。
first
first=take(1),返回数据集中的第一个元素。
foreach
循环遍历数据集中的每个元素,运行相应的逻辑。
collect
返回RDD所有元素,将计算结果回收到Driver端。Note:如果数据量比较大的时候,尽量不要使用collect函数,因为这可能导致Driver端内存溢出问题。
countByValue
统计一个RDD中各个value的出现次数。返回一个map,map的key是元素的值,value是出现的次数。
countByKey
统计一个RDD中各个Key的出现次数。
reduce。
将RDD中元素两两传递给输入函数,同时产生一个新的值,新产生的值与RDD中下一个元素再被传递给输入函数直到最后只有一个值为止。
控制算子
概念:
控制算子有三种,cache,persist,checkpoint,以上算子都可以将RDD持久化,持久化的单位是partition。cache和persist都是懒执行的。必须有一个action类算子触发执行。checkpoint算子不仅能将RDD持久化到磁盘,还能切断RDD之间的依赖关系。
cache
默认将RDD的数据持久化到内存中。cache是懒执行。
注意:chche () = persist()=persist(StorgeLevel.Memory_Only)
测试cache文件:
文件:见“NASA_access_log_Aug95”文件。
测试代码:
SparkConf conf = new SparkConf();
conf.setMaster("local").setAppName("CacheTest");
JavaSparkContext jsc =new JavaSparkContext(conf);
JavaRDD
lines =lines.cache();
long startTime = System.currentTimeMillis();
long count =lines.count();
long endTime = System.currentTimeMillis();
System.out.println("共"+count+"条数据,"+"初始化时间+cache时间+计算时间="+(endTime-startTime));
long countStartTime = System.currentTimeMillis();
long countrResult =lines.count();
long countEndTime = System.currentTimeMillis();
System.out.println("共"+countrResult+"条数据,"+"计算时间="+ (countEndTime-countStartTime));
jsc.stop();
persist:
可以指定持久化的级别。最常用的是MEMORY_ONLY和MEMORY_AND_DISK。”_2”表示有副本数。
持久化级别如下:
¬ cache和persist的注意事项:
1. cache和persist都是懒执行,必须有一个action类算子触发执行。
2. cache和persist算子的返回值可以赋值给一个变量,在其他job中直接使用这个变量就是使用持久化的数据了。
3. cache和persist算子后不能立即紧跟action算子。
错误:rdd.cache().count() 返回的不是持久化的RDD,而是一个数值了。
checkpoint
checkpoint将RDD持久化到磁盘,还可以切断RDD之间的依赖关系。
checkpoint 的执行原理:
1. 当RDD的job执行完毕后,会从finalRDD从后往前回溯。
2. 当回溯到某一个RDD调用了checkpoint方法,会对当前的RDD做一个标记。
3. Spark框架会自动启动一个新的job,重新计算这个RDD的数据,将数据持久化到HDFS上。
优化:对RDD执行checkpoint之前,最好对这个RDD先执行cache,这样新启动的job只需要将内存中的数据拷贝到HDFS上就可以,省去了重新计算这一步。
使用:
SparkConf conf = new SparkConf();
conf.setMaster("local").setAppName("checkpoint");
JavaSparkContext sc = new JavaSparkContext(conf);
sc.setCheckpointDir("./checkpoint");//设置checkPoint的路径
JavaRDD
parallelize.checkpoint();
parallelize.count();
sc.stop();
代码示例:
代码流程:
/**
* demo01 :熟悉代码的流程以及用scala实现单词统计小demo
* Spark代码流程
* 1、创建SparkConf对象 设置运行模式、项目名称等信息
* 2、创建SparkContext对象
* 3、基于Spark上下文创建一个rdd 、对Rdd进行处理
* 4、执行行动类算子
* 5、关闭Spark上下文对象
*
*/
object Process {
def main(args: Array[String]): Unit = {
val conf=new SparkConf()
conf.setMaster("local").setAppName("test")
val sc=new SparkContext(conf);
val lineRdd=sc.textFile("./word.txt");
val wordRdd=lineRdd.flatMap{line => {line.split(" ")}};//读取的每行数据按照空格分割 返回的是字符串数组。然后再将字符串数组拍扁。
val pairRdd=wordRdd.map{word => {(word,1)}}//读取每个单词然后记为1
val reduceRdd=pairRdd.reduceByKey((v1:Int,v2:Int) =>{v1+v2})//将相同的Key执行加法操作
reduceRdd.foreach{println}
sc.stop()
println("===========");
}
}
转换算子
/**
* demo02
* spark转换算子
* 1、filter:参数是函数,函数会过滤掉不符合条件的元素,返回值是新的RDD。
* 2、sample:随机抽样算子,根据传进去的小数按比例进行又放回或者无放回的抽样。
* 3、map:在Map中,我们会传入一个函数,该函数对每个输入都会返回一个数组(或者元组、集合)(而不是一个元素)。
* 4、flatMap:是map的一种扩展。在flatMap中,我们会传入一个函数,该函数对每个输入都会返回一个数组或者元组、集合(而不是一个元素),然后,flatMap把生成的多个集合(数组)“拍扁”成为一个集合(数组)或者字符串RDD。
* 5、reduceByKey:将K、V格式的Rdd中相同的Key根据相应的逻辑进行处理。 如:单词统计的加法操作。
* 6、distinct:没有参数,将RDD里的元素进行去重操作。
* 7、intersection:参数是RDD,求出两个RDD的共同元素。
* 8、subtract():参数是RDD,将原RDD里和参数RDD里相同的元素去掉 即:返回的数据是原RDD中不和参数RDD中相同的元素。
* 9、cartesian:参数是RDD,求两个RDD的笛卡儿积。
* 10、sortByKey:作用在K,V格式的RDD上,对key进行升序或者降序排序.
* 11、mapPartiiton:与map类似,遍历的单位是每个partition上的数据。
* 12、groupByKey:将rdd按照key分组。
* 13、zipWithIndex: 该函数将RDD中的元素和这个元素在RDD中的索引号(从0开始)组合成(K,V)对
*/
object NormalTransFrom {
def main(args: Array[String]): Unit = {
val conf=new SparkConf()
conf.setMaster("local").setAppName("test")
val sc=new SparkContext(conf);
val lineRdd=sc.textFile("./data.txt");//读取的所有数据
/**
* 过滤出符合条件的元素,true保留,false过滤掉。
*/
println("***************1、已进入filter方法*********************");
val filterRdd=lineRdd.filter { line => line.equals("hello bjsxt") }//line是所有文件数据中读取的一行数据
//line.equals("hello bjsxt") 表示:读取的一行数据为hello bjsxt的数据
val result=filterRdd.collect();//返回RDD所有元素,将计算结果收集到Driver端
result.foreach{
elem => {
println(elem);
}
}
//result.foreach(println);
println("***************filter方法结束!*********************");
/**
* 随机抽样算子,根据传进去的小数按比例进行又放回或者无放回的抽样。
* 第一个参数:如果为true代表有放回的抽样,false代表无放回的抽样
* 第二个参数代表抽样的比例
* 第三个参数代表种子:如果对同一批数据相同种子随机抽样,那么收到的结果相同。
* 也就是说如果前两个参数不变的情况下,设置种子值固定 那么随机抽样出的数据相同
*/
println("***************2、已进入sample方法*********************");
val sampleRdd=lineRdd.sample(true, 0.5)
sampleRdd.foreach{
println
}
println("***************sample方法结束!*********************");
println("***************3、map与faltMap方法开始!*********************");
/*map返回的是元组信息 flatMap返回的是字符串RDD*/
val wordRdd=lineRdd.flatMap{line => {line.split(" ")}};//将读取的每行数据按空格分割,然后返回字符串数组,有多少行数据就会返回多少字符串数组,最后将所有的字符串数组进行扁平化为一个字符串RDD。
val pairRdd=wordRdd.map{word => {(word,1)}}//遍历每个单词 然后记为1 返回的是K、V格式的元组信息
val reduceRdd=pairRdd.reduceByKey((v1:Int,v2:Int) =>{v1+v2})//将相同key的元组 进行相加
reduceRdd.foreach{println}
/*map返回的是字符串数组 flatMap返回的是字符串RDD*/
val mapResult= lineRdd.map{lines =>lines.split(" ")};//map函数执行后返回的是字符串数组RDD
val flatMapResult= lineRdd.flatMap{lines =>lines.split(" ")};//flatMap函数执行后返回的是字符串RDD
val result1=mapResult.collect();//collect 函数返回Array[Array[String]] result是二维数组
result1.foreach(println);
/*map返回的是字符串集合 flatMap返回的是字符型集合*/
val books = List("Hadoop","Hive","HDFS")//List[String]
val mapResult2=books.map(s => s.toUpperCase)//List[String] = List(HADOOP, HIVE, HDFS)
val flatMapResult2=books.flatMap(s => s.toUpperCase)//List[Char] = List(H, a, o, o, p, H, i, v, e, H, D, F, S)
println(mapResult2);
println("***************map与faltMap方法结束!*********************");
println("***************4、distinct方法开始!*********************");
val dintinctResult=lineRdd.distinct();//这里是去除相同的行
dintinctResult.foreach {println}
println("***************distinct方法结束!*********************");
println("***************5、union方法开始!*********************");
val flow = sc.parallelize(List(("String1",1),("String2",2),("String3",3)));
val org = sc.parallelize(List(("String3",3),("String4",1),("String1",2)));
flow.union(org);
val u = flow.union(org);
u.foreach(println);
/* 输出: RDDs的union操作,把2个RDDs的元素合并起来。
(String1,1)
(String2,2)
(String3,3)
(String3,3)
(String4,1)
(String1,2)
* */
println("***************union方法结束!*********************");
println("***************6、intersection方法开始!*********************");
val same=flow.intersection(org);
same.foreach(println)
/*
* (String3,3)
*
*
*/
println("***************intersection方法结束!*********************");
println("***************7、subtract方法开始!*********************");
val different=flow.subtract(org);
different.foreach(println)
/*
* (String2,2)
(String1,1)
*/
println("***************7、subtract方法结束!*********************");
println("***************8、cartesian方法开始!*********************");
val cartesian=flow.cartesian(org)
cartesian.foreach(println)
/*
((String1,1),(String3,3))
((String1,1),(String4,1))
((String1,1),(String1,2))
((String2,2),(String3,3))
((String2,2),(String4,1))
((String2,2),(String1,2))
((String3,3),(String3,3))
((String3,3),(String4,1))
((String3,3),(String1,2))
*/
println("***************8、cartesian方法结束!*********************");
println("=========9、sortByKey的使用===========")
val mapRdd1=reduceRdd.map(tuple =>{(tuple._2,tuple._1)})//将reduceRdd的map中的key和value位置转换
val sortRdd=mapRdd1.sortByKey()//默认升序排序 当方法参数为false时降序排序
val mapRdd2=sortRdd.map(tuple =>{(tuple._2,tuple._1)})
mapRdd2.foreach{println}
println("========10、first方法的使用==========");
val firstResult=mapRdd2.first();//返回数据集中的第一个元素。
println("firstResult="+firstResult);
println("========11、take(n)方法的使用==========");
val takenResult=mapRdd2.take(2);//返回一个包含数据集前n个元素的集合。
takenResult.foreach{
println
}
println("========12、mapPartitions方法的开始==========");
val rdd1 = sc.makeRDD(Array(1,2,3,4,5,6),3)
val mapResults = rdd1.mapPartitions(iter=>{
println("插入数据库")
iter
})
mapResults.foreach { println }
println("========mapPartitions方法的结束==========");
println("========13、groupByKey方法的开始==========");
val rdd13 = sc.makeRDD(Array(
(1,"a"),
(1,"b"),
(2,"c"),
(3,"d")
))
val result13 = rdd13.groupByKey()
result13.foreach(println)
/*
* (1,CompactBuffer(a, b))
* (3,CompactBuffer(d))
* (2,CompactBuffer(c))
*/
println("========groupByKey方法的结束==========");
println("========14、zipWithIndex方法的开始==========");
val rdd14 = sc.makeRDD(Array((1,"a"),(2,"b"),(3,"c")))
val result14 = rdd14.zipWithIndex()
result14.foreach(println)
/*
*((1,a),0)
*((2,b),1)
*((3,c),2)
*/
println("========zipWithIndex方法的结束==========");
sc.stop()
}
}
/**
* Demo03
* Spark中Key-Value型转换算子
* 1、join:内连接join;相当于SQL中的内关联join,只返回两个RDD根据K可以关联上的结果,join只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
* 2、leftOuterJoin:类似于SQL中的左外关联left outer join,返回结果以前面的RDD为主,关联不上的记录为空。只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
* 3、rightOuterJoin:类似于SQL中的有外关联right outer join,返回结果以参数中的RDD为主,关联不上的记录为空。只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
* 4、cogroup:当调用类型(K,V)和(K,W)的数据上时,返回一个数据集(K,(Iterable
* 5、zip:将两个RDD中的元素(KV格式/非KV格式)变成一个KV格式的RDD,两个RDD的个数必须相同。
*/
object K_V_Transformations {
def main(args: Array[String]): Unit = {
val conf =new SparkConf();
conf.setMaster("local").setAppName("sparkTest01")
val sc=new SparkContext(conf);
//创建两个RDD
val rdd1 = sc.parallelize(Array(("aa",1),("bb",2)))
val rdd2 = sc.parallelize(Array(("aa",3),("dd",1)))
println("*************1、Join方法开始*************");
val result=rdd1.join(rdd2);//(String, (Int, Int)) 内连接后的RDD是K、V格式的元组,元组的value值是元组。
result.foreach(println)
/**
* (aa,(1,3))
*/
println("*************Join方法结束*************");
println("*************2、leftOuterJoin方法开始*************");
var leftResult=rdd1.leftOuterJoin(rdd2);
leftResult.foreach(println)
/*
* (aa,(1,Some(3)))
* (bb,(2,None))
*/
println("*************leftOuterJoin方法结束*************");
println("*************3、rightOuterJoin方法开始*************");
var rightResult=rdd1.rightOuterJoin(rdd2);
rightResult.foreach(println)
/*
* (aa,(Some(1),3))
* (dd,(None,1))
*/
println("*************rightOuterJoin方法结束*************");
println("*************4、cogroup方法开始*************");
val cogroupResult=rdd1.cogroup(rdd2);
cogroupResult.foreach(println);
/*
* (aa,(CompactBuffer(1),CompactBuffer(3)))
* (dd,(CompactBuffer(),CompactBuffer(1)))
* (bb,(CompactBuffer(2),CompactBuffer()))
*/
println("*************cogroup方法结束*************");
println("*************5、zip方法开始*************");
val nameRDD = sc.makeRDD(Array("zhangsan","lisi","wangwu"))
val scoreRDD = sc.parallelize(Array(1,2,3))
val zipResult = nameRDD.zip(scoreRDD)
zipResult.foreach(println)
/*
* (zhangsan,1)
* (lisi,2)
* (wangwu,3)
*/
println("*************zip方法结束*************");
}
}
行动算子
/**
* Demo04 行动算子
* 1、collect:返回RDD所有元素,将计算结果回收到Driver端。
* 2、count:返回原RDD中数据的个数。
* 3、countByKey:统计一个RDD中各个Key的出现次数。
* 4、countByValue:统计一个RDD中各个value的出现次数。返回一个map,map的key是元素的值,value是出现的次数。
* 5、foreachPartition:遍历的数据是每个partition的数据。
* 6、foreach:循环遍历数据集中的每个元素,运行相应的逻辑。
* 7、first:返回数据集中的第一个元素。
* 8、take:返回一个包含数据集前n个元素的集合。
* 9、reduce:根据聚合逻辑聚合数据集中的每个元素。
* 将RDD中元素两两传递给输入函数,同时产生一个新的值,新产生的值与RDD中下一个元素再被传递给输入函数直到最后只有一个值为止。
*
*/
object Action {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
conf.setMaster("local").setAppName("collect")
val sc = new SparkContext(conf)
val lines = sc.textFile("./word.txt")
lines.collect().foreach { println }
val result = lines.count()
val rdd1 = sc.parallelize(List(("a",100),("b",200), ("a",300), ("c",400)))
val result2 = rdd1.countByKey()
result2.foreach(println)
val rdd2 = sc.makeRDD(List(
("a",100),
("a",100),
("b",300),
("c",400)
))
val rdd3 = rdd2.countByValue()
rdd3.foreach(println)
val rdd4 = sc.makeRDD(Array(1,2,3,4,5))
rdd4.foreachPartition { iter => {
println("连接数据库。。。")
while(iter.hasNext){
println(iter.next())
}
} }
val rdd5 = sc.makeRDD(Array(1,2,3,4,5))
val result5 = rdd5.reduce(_+_)//根据聚合逻辑聚合数据集中的每个元素。
println(result5)
sc.stop()
}
}
控制算子
/**
* cache和persist都是懒执行,必须有一个action类算子触发执行。
* cache是吧读取的数据放到内存里
* 而persist默认默认放在内存 但是也可以指定存放的位置
* cache()=persist()=persist()=persist(StorageLevel..MEMORY_ONLY)
* cache和persist的注意事项:
* 1.cache和persist都是懒执行,必须有一个action类算子触发执行。
* 2.cache和persist算子的返回值可以赋值给一个变量,在其他job中直接使用这个变量就是使用持久化的数据了。
* 3.cache和persist算子后不能立即紧跟action算子。
* 错误:rdd.cache().count() 返回的不是持久化的RDD,而是一个数值了。
*/
object Cache {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
conf.setMaster("local").setAppName("cacheTest")
val sc = new SparkContext(conf)
var lines = sc.textFile("./NASA_access_log_Aug95")
lines = lines.cache()//将结果放到内存里
val startTime = System.currentTimeMillis()
val count = lines.count()
val endTime = System.currentTimeMillis()
println("共"+count +"条数据,用时"+(endTime-startTime)+"ms")//2815ms
val startTime1 = System.currentTimeMillis()
val count1 = lines.count()
val endTime1 = System.currentTimeMillis()
println("共"+count1 +"条数据,用时"+(endTime1-startTime1)+"ms")//84m
sc.stop()
}
}
/**
* checkpoint将RDD持久化到磁盘,还可以切断RDD之间的依赖关系。
*/
object CheckPoint {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
conf.setMaster("local").setAppName("checkpoint")
val sc = new SparkContext(conf)
sc.setCheckpointDir("./checkpoint")
val lines = sc.textFile("./words.txt")
lines.checkpoint()
lines.foreach { println}
sc.stop()
}
}
---------------------
作者:小飞猪666
来源:CSDN
原文:https://blog.csdn.net/yangshaojun1992/article/details/78358801
版权声明:本文为博主原创文章,转载请附上博文链接!