大数据Spark算子

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,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 = jsc.textFile("./NASA_access_log_Aug95");


 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 = sc.parallelize(Arrays.asList(1,2,3));

 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,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

版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(大数据Spark算子)