【3天掌握Spark】-- RDD函数

Spark之RDD函数

RDD 函数分类

RDD 的操作主要可以分为 TransformationAction 两种。

  • Transformation 转换,将1个RDD转换为另一个RDD
  • Action 触发,当1个RDD调用函数以后,触发一个Job执行(调用Action函数以后,返回值不是RDD)

在这里插入图片描述
在这里插入图片描述
RDD中2种类型操作函数:Transformation(lazy)和Action(eager)函数
在这里插入图片描述

Transformation转换函数
在这里插入图片描述
Action触发函数,触发一个Job执行
在这里插入图片描述

RDD 中常见函数概述

RDD中包含很多函数,主要可以分为两类:Transformation转换函数和Action函数。
在这里插入图片描述
主要常见使用函数如下,每个函数通过演示范例讲解。
在这里插入图片描述

1、分区操作函数
	对RDD中每个分区数据进行操作
	
2、重分区函数
	调整RDD中分区数目,要么变大,要么变小

3、聚合函数
	对RDD中数据进行聚合统计,比如使用reduce、redueBykey等
	
4、关联函数
	对2个RDD进行JOIN操作,类似SQL中JOIN,分为:等值JOIN、左外连接和右外连接、全外连接fullOuterJoin

RDD 函数之基本函数使用

RDD中map、filter、flatMap及foreach等函数为最基本函数,都是对RDD中`每个元素进行操作,将元素传递到函数中进行转换`。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210521211249110.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80ODE0Mzk5Ng==,size_16,color_FFFFFF,t_70)

编写词频统计WordCount程序,使用基本函数

/**
 * 演示RDD中基本函数使用
 */
object _01SparkBasicTest {
	
	def main(args: Array[String]): Unit = {
		// 创建SparkContext实例对象,传递SparkConf对象,设置应用配置信息
		val sc: SparkContext = {
			// a. 创建SparkConf对象
			val sparkConf = new SparkConf()
				.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
				.setMaster("local[2]")
			// b. 传递sparkConf对象,构建SparkContext实例
			SparkContext.getOrCreate(sparkConf)
		}
		
		// step1. 读取数据
		val inputRDD: RDD[String] = sc.textFile("datas/wordcount/input.data", minPartitions = 2)
		
		// step2. 处理数据
		val resultRDD: RDD[(String, Int)] = inputRDD
			// 过滤数据
			.filter(line => null != line && line.trim.length > 0)
			// 分割单词
			.flatMap(line => line.trim.split("\\s+"))
			// 转换为二元组
			.map(word => word -> 1)
			// 按照单词分组,对组内数据进行聚合求和
			.reduceByKey((tmp, item) => tmp + item) // TODO: 隐式转换,将RDD对象抓好为PairRDDFunctions对象,调用方法
		
		// step3. 输出数据
		resultRDD.foreach(item => println(item))
		
		// 应用结束,关闭资源
		sc.stop()
	}
	
}

RDD 函数之分区操作函数

每个RDD由多分区组成的,实际开发建议对每个分区数据的进行操作,map函数使用mapPartitions代替foreach函数使用foreachPartition代替

[前面编写WordCount词频统计代码中,使用map函数和forearch函数,针对RDD中每个元素操作,并不是针对每个分区数据操作的,如果针对分区操作:mapPartitions和foreachPartition]
在这里插入图片描述
针对分区数据进行操作时,函数的参数类型:迭代器Iterator,封装分区中所有数据

针对词频统计WordCount代码进行修改,针对分区数据操作,范例代码如下:

/**
 * 分区操作函数:mapPartitions和foreachPartition
 */
object _02SparkIterTest {
	
	def main(args: Array[String]): Unit = {
		// 创建SparkContext实例对象,传递SparkConf对象,设置应用配置信息
		val sc: SparkContext = {
			// a. 创建SparkConf对象
			val sparkConf = new SparkConf()
				.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
				.setMaster("local[2]")
			// b. 传递sparkConf对象,构建SparkContext实例
			SparkContext.getOrCreate(sparkConf)
		}
		
		// step1. 读取数据
		val inputRDD: RDD[String] = sc.textFile("datas/wordcount.data", minPartitions = 2)
		
		// step2. 处理数据
		val resultRDD: RDD[(String, Int)] = inputRDD
			// 过滤数据
			.filter(line => line.trim.length != 0 )
			// 对每行数据进行单词分割
			.flatMap(line => line.trim.split("\\s+"))
			// 转换为二元组
    		//.map(word => word -> 1)
			/*
			  def mapPartitions[U: ClassTag](
			      f: Iterator[T] => Iterator[U],
			      preservesPartitioning: Boolean = false
			  ): RDD[U]
			 */
    		.mapPartitions(iter => iter.map(word => (word, 1)))
			// 分组聚合
			.reduceByKey((tmp, item) => tmp + item)
		
		// step3. 输出数据
		//resultRDD.foreach(item => println(item))
		/*
		  def foreachPartition(f: Iterator[T] => Unit): Unit
		 */
		resultRDD.foreachPartition(iter => iter.foreach(item => println(item)))
		
		// 应用结束,关闭资源
		sc.stop()
	}
	
}

分区操作的好处
在这里插入图片描述

RDD 函数之重分区函数

如何对RDD中分区数目进行调整(增加分区或减少分区),在RDD函数中主要有如下三个函数。
在这里插入图片描述

上述2个函数最为关键:
	- 增加RDD分区数目:repartition
	- 减少RDD分区数目:coalesce,不产生Shuffle
/**
 * 分区操作函数:mapPartitions和foreachPartition
 */
object _02SparkPartitionTest {
	
	def main(args: Array[String]): Unit = {
		// 创建SparkContext实例对象,传递SparkConf对象,设置应用配置信息
		val sc: SparkContext = {
			// a. 创建SparkConf对象
			val sparkConf = new SparkConf()
				.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
				.setMaster("local[2]")
			// b. 传递sparkConf对象,构建SparkContext实例
			SparkContext.getOrCreate(sparkConf)
		}
		
		// step1. 读取数据
		val inputRDD: RDD[String] = sc.textFile("datas/wordcount.data", minPartitions = 2)
		println(s"raw rdd partitions = ${inputRDD.getNumPartitions}")
		
		// TODO: 增加RDD分区数目
		val etlRDD: RDD[String] = inputRDD.repartition(3)
		println(s"etl rdd partitions = ${etlRDD.getNumPartitions}")
		
		// step2. 处理数据
		val resultRDD: RDD[(String, Int)] = inputRDD
			// 过滤数据
			.filter(line => line.trim.length != 0 )
			// 对每行数据进行单词分割
			.flatMap(line => line.trim.split("\\s+"))
			// 转换为二元组
    		//.map(word => word -> 1)
			/*
			  def mapPartitions[U: ClassTag](
			      f: Iterator[T] => Iterator[U],
			      preservesPartitioning: Boolean = false
			  ): RDD[U]
			 */
    		.mapPartitions(iter => iter.map(word => (word, 1)))
			// 分组聚合
			.reduceByKey((tmp, item) => tmp + item)
		
		// step3. 输出数据
		//resultRDD.foreach(item => println(item))
		/*
		  def foreachPartition(f: Iterator[T] => Unit): Unit
		 */
		// TODO: 降低结果RDD分区数目
		val outputRDD: RDD[(String, Int)] = resultRDD.coalesce(1)
		println(s"output rdd partitions = ${outputRDD.getNumPartitions}")
		outputRDD.foreachPartition(iter => iter.foreach(item => println(item)))
		
		// 应用结束,关闭资源
		sc.stop()
	}
	
}

调整分区的场景
在这里插入图片描述

RDD 函数之RDD 中聚合函数

查看列表List中聚合函数reduce和fold源码如下:
在这里插入图片描述
通过代码,看看列表List中聚合函数使用:
在这里插入图片描述
在这里插入图片描述
fold聚合函数,比reduce聚合函数,多提供一个可以初始化聚合中间临时变量的值参数:

在这里插入图片描述
聚合操作时,往往聚合过程中需要中间临时变量(到底时几个变量,具体业务而定),如下案例
在这里插入图片描述
在RDD中提供类似列表List中聚合函数reduce和fold,查看如下:
在这里插入图片描述

RDD 函数之PairRDDFunctions 聚合函数

在Spark中有一个object对象PairRDDFunctions,主要针对RDD的数据类型是Key/Value对的数据提供函数,方便数据分析处理。比如使用过的函数:reduceByKey、groupByKey等。

*ByKey函数将相同Key的Value进行聚合操作的,省去先分组再聚合。
在这里插入图片描述
第一类:分组函数groupByKey
在这里插入图片描述
第二类:分组聚合函数reduceByKey和foldByKey
在这里插入图片描述
第三类:分组聚合函数aggregateByKey
在这里插入图片描述

RDD 函数之关联JOIN函数

当两个RDD的数据类型为二元组Key/Value对时,可以依据Key进行关联Join。
在这里插入图片描述
RDD中关联JOIN函数都在PairRDDFunctions中
在这里插入图片描述
具体看一下join(等值连接)函数说明:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spark中的RDD(Resilient Distributed Datasets)是一种分布式的数据结构,它可以被分割成多个分区,每个分区可以在不同的节点上进行计算。RDD提供了一系列的转换和操作函数,可以对RDD进行各种操作。 RDD转换函数包括map、filter、flatMap、union、distinct、groupByKey、reduceByKey、sortByKey等。这些函数可以对RDD进行转换操作,生成新的RDDRDD操作函数包括count、collect、reduce、take、foreach等。这些函数可以对RDD进行操作,返回结果或者将结果输出到外部系统。 在使用RDD时,需要注意一些问题,如RDD的惰性计算、RDD的持久化、RDD的分区等。同时,还需要根据实际情况选择合适的RDD转换和操作函数,以达到最优的计算效果。 总之,Spark中的RDD转换和操作函数是非常重要的,掌握它们可以帮助我们更好地使用Spark进行分布式计算。 ### 回答2: Spark是一个基于内存计算的分布式计算框架,可以实现大规模数据集的快速处理。在Spark中,RDD(弹性分布式数据集)是数据处理的核心概念,它是一种可以分区、并行计算和容错的不可变数据结构。而Spark中的函数式编程模型则将RDD的转换与操作都看做是函数的调用,从而简洁明了,易于理解和操作。 在Spark中,解决一个具体问题通常涉及一系列RDD的转换和操作。RDD的转换包括对原有RDD进行过滤、映射、聚合等处理,得到新的RDD;操作则是对新的RDD进行输出、保存、统计、排序等操作。以下介绍几种常见的RDD转换和操作函数。 1. map函数 map函数是一种转换函数,它可以将一个RDD中每个元素通过一个用户定义的函数映射到另一个RDD中,并得到新的RDD。例如,将一个整型RDD中的每个元素都乘以2后得到一个新的整型RDD: ``` val rdd1 = sc.parallelize(Array(1, 2, 3, 4)) val rdd2 = rdd1.map(x => x*2) ``` 2. filter函数 filter函数也是一种转换函数,它可以根据用户定义的条件过滤一个RDD中的元素,并得到一个新的RDD。例如,将一个字符串RDD中长度大于5的元素过滤出来得到一个新的字符串RDD: ``` val rdd1 = sc.parallelize(Array("hello", "world", "spark", "rdd")) val rdd2 = rdd1.filter(x => x.length > 5) ``` 3. reduce函数 reduce函数是一种操作函数,它可以将一个RDD中的元素按照用户定义的函数进行聚合并得到一个结果。例如,将一个整型RDD中的所有元素相加得到一个整数结果: ``` val rdd1 = sc.parallelize(Array(1, 2, 3, 4)) val result = rdd1.reduce((x, y) => x + y) ``` 4. collect函数 collect函数也是一种操作函数,它可以将一个RDD中的所有元素收集起来并输出到Driver端。然而,使用collect函数需要注意RDD的大小,如果RDD很大,就可能会出现内存溢出的情况。例如,将一个整型RDD中的所有元素收集起来并输出到屏幕: ``` val rdd1 = sc.parallelize(Array(1, 2, 3, 4)) val result = rdd1.collect() result.foreach(println) ``` 5. saveAsTextFile函数 saveAsTextFile函数也是一种操作函数,它可以将一个RDD中的所有元素保存到指定的文本文件中。例如,将一个字符串RDD中的所有元素保存到hdfs的一个文本文件中: ``` val rdd1 = sc.parallelize(Array("hello", "world", "spark", "rdd")) rdd1.saveAsTextFile("hdfs://localhost:8020/user/abc/output") ``` 总之,Spark中的RDD转换和操作函数具有弹性、高效、简单等特点,能够满足各种大规模数据处理需求。需要特别注意的是,Spark中的函数式编程模型是基于JVM的,因此要充分利用内存和CPU资源,需要对集群配置和调优进行一定的优化和测试。 ### 回答3: Spark中的RDD(Resilient Distributed Datasets)是分布式的弹性数据集,它可以在大规模集群上并行化地计算,并且提供了一系列的转换和操作函数。其中,Spark提供的Spark函数简单易用,具有高效的数据处理能力,可以帮助开发者快速开发分布式应用程序。 RDD转换函数是将一个RDD转换成另一个RDD函数,转换后的RDD通常包含了数据处理、筛选和过滤后的新数据集,可以用来接着进行后续的计算。 例如,map函数可以将RDD中的每个元素应用一个函数,然后返回一个新的转换过的RDD: ``` val originalData = sc.parallelize(List(1, 2, 3, 4, 5)) val mappedData = originalData.map(x => x * 2) ``` 这里,map函数将原始数据中的每个元素都乘上了2,返回了一个新的RDD。 除了map函数, 还有flatMap、filter、groupBy等常用的转换函数,都可以帮助我们对RDD做出各种各样的数据处理和转换。 RDD操作函数则是对RDD进行真正的计算操作,例如reduce、count、collect等函数,这些函数会触发Spark的分布式计算引擎执行真正的计算任务。 比如,reduce函数可以将RDD中的所有元素进行聚合,返回一个单一的结果: ``` val originalData = sc.parallelize(List(1, 2, 3, 4, 5)) val reducedData = originalData.reduce(_ + _) ``` 这里,reduce函数将原始数据中的所有元素进行相加操作,返回了一个整数类型的结果。 Spark提供的操作函数非常丰富,从基本的聚合、排序、统计操作,到高级的机器学习和图形处理等操作,开发者可以根据不同的业务需求灵活选择使用。 总之,Spark中的RDD转换和操作函数是分布式数据处理的核心之一,通过这些函数,开发者能够方便地对海量数据进行分布式的计算和处理。同时,Spark也提供了丰富的API和工具,便于开发者进行高效的Spark应用程序开发。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值