SPARK RDD基础及常用算子浅谈

3 篇文章 2 订阅
1 篇文章 0 订阅

SPARK RDD基础及常用算子浅谈

一、什么是SPARK RDD:

      RDD是将数据项拆分为多个分区的集合,存储在集群的工作节点上的内存中,并执行正确的操作。RDD是用于数据转换的接口。RDD指向了存储在HDFS、Cassandra、HBase等、或缓存(内存、内存+磁盘、仅磁盘等),或在故障或缓存收回时重新计算其他RDD分区中的数据。
      RDD是弹性分布式数据集(Resilient Distributed Datasets):

  • 分布式数据集:RDD是只读的、分区记录的集合,每个分区分布在集群的不同节点上;RDD并不存储真正的数据,只是对数据和操作的描述。
  • 弹性:RDD默认存放在内存中,当内存不足,Spark自动将RDD写入磁盘。
  • 容错性:根据数据血统,可以自动从节点失败中恢复分区。
二、RDD与DAG:
  • 两者都是Spark提供的核心抽象。
  • DAG(有向无环图)反映了RDD之间的依赖关系。
    在这里插入图片描述
三、RDD的特性:
  1. 一系列的分区(分片)信息,每个任务处理一个分区;
  2. 每个分区上都有compute函数,计算该分区中的数据;
  3. RDD之间有一系列的依赖;
  4. 分区函数决定数据(key-value)分配至哪个分区;
  5. 最佳位置列表,将计算任务分派到其所在处理数据块的存储位置。
四、RDD编程流程:
RDD创建
RDD转换
RDD持久化
RDD执行
五、RDD的创建:

a.使用集合创建RDD:

  • Spark默认会根据集群的情况来设置分区的数量,也可以通过parallelize()第二参数来指定;
  • Spark会为每一个分区运行一个任务进行处理。
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.count
rdd.partitions.size
val rdd=sc.parallelize(List(1,2,3,4,5,6),5)
rdd.partitions.size
val rdd=sc.makeRDD(List(1,2,3,4,5,6))

b.通过加载文件产生RDD:

  • 加载“file://……”时,以local运行仅需一份本地文件,以Spark集群方式运行,应保证每个节点均有该文件的本地副本;
  • 文件中的一行文本作为RDD的一个元素
val distFile=sc.textFile("file:///home/hadoop/data/hello.txt")
distFile.count
val distHDFSFile=sc.textFile("hdfs://hadoop000:8020/hello.txt")

支持目录、压缩文件以及通配符:

  • Spark默认访问HDFS;
  • Spark默认为HDFS文件的每一个数据块创建一个分区,也可以通过textFile()第二个参数指定,但只能比数据块数量多。
sc.textFile("/my/directory")
sc.textFile("/my/directory/*.txt")
sc.textFile("/my/directory/*.gz")

c.其他创建RDD的方法:
      SparkContext.wholeTextFiles():可以针对一个目录中的大量小文件返回<filename,fileContent>作为PairRDD:

  • 普通RDD:org.apache.spark.rdd.RDD[data_type]
  • PairRDD:org.apache.spark.rdd.RDD[(key_type,value_type)]
六、RDD分区:

      分区是RDD被拆分并发送到节点的不同块之一:

  • 我们拥有的分区越多,得到的并行性就越强;
  • 每个分区都是被分发到不同Worker Node的候选者;
  • 每个分区对应一个Task。
    在这里插入图片描述
七、RDD的操作:

      RDD操作分为lazy与non-lazy两种:

  • Transformation(lazy):也称转换操作、转换算子;
  • Actions(non-lazy):立即执行,也称动作操作、动作算子。

a.RDD转换算子:对于转换操作,RDD的所有转换都不会直接计算结果。

  • 仅记录作用于RDD上的操作;
  • 当遇到动作算子(Action)时才会进行真正计算。
    在这里插入图片描述
    (1)RDD常用转换算子:
    i.map算子:
  • 对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD;
  • 任何原RDD中的元素在新RDD中都有且只有一个元素与之对应;
  • 输入分区与输出分区一一对应。
//将原RDD中每个元素都乘以2来产生一个新的RDD
val a=sc.parallelize(1 to 9)
val b=a.map(x=>x*2)
a.collect
b.collect

//map把普通RDD变成PairRDD
val a=sc.parallelize(List("dog","tiger","lion","cat","panther","eagle"))
val b=a.map(x=>(x,1))
b.collect

ii.filter算子:
      对元素进行过滤,对每个元素应用指定函数,返回值为true的元素保留在新的RDD中。

val a=sc.parallelize(1 to 10)
a.filter(_%2==0).collect      
a.filter(_<4).collect	
//map&filter
val rdd=sc.parallelize(List(1 to 6))
val mapRdd=rdd.map(_*2)
mapRdd.collect
val filterRdd=mapRdd.filter(_>5)
filterRdd.collect

iii.mapValues算子:
      原RDD中的Key保持不变,与新的Value一起组成新的RDD中的元素,仅适用于PairRDD。

// 输出结果:Array((3,xdogx), (5,xtigerx), (4,xlionx), (3,xcatx), (7,xpantherx), (5,xeaglex))
val a=sc.parallelize(List("dog","tiger","lion","cat","panther","eagle"))
val b=a.map(x=>(x.length,x))
b.mapValues("x"+_+"x").collect

iv.其他常用转换算子:

  • distinct
  • reduceByKey
  • sortByKey
  • groupByKey
  • union
  • join
val dis = sc.parallelize(List(1,2,3,4,5,6,7,8,9,9,2,6))
dis.distinct.collect
dis.distinct(2).partitions.length

val a = sc.parallelize(List("dog", "salmon", "pig"), 3)
val f = a.map(x=>(x.length,x))
f.reduceByKey((a,b)=>(a+b)).collect
f.reduceByKey(_+_).collect
f.groupByKey.collect

val a = sc.parallelize(List("dog", "salmon", "pig"), 3)
val f = a.map(x=>(x.length,x))
f.sortByKey().collect
f.sortByKey(false).collect

val u1 = sc.parallelize(1 to 3)
val u2 = sc.parallelize(3 to 4)
u1.union(u2).collect
(u1 ++ u2).collect
u1.intersection(u2).collect

val j1 = sc.parallelize(List("abe", "abby", "apple"))
                                                                           .map(a => (a, 1))
val j2 = sc.parallelize(List("apple", "beatty", "beatrice")).map(a => (a, 1))
j1.join(j2).collect
j1.leftOuterJoin(j2).collect
j1.rightOuterJoin(j2).collect

b.RDD动作算子:

  • 本质上动作算子通过SparkContext执行提交作业操作,触发RDD DAG(有向无环图)的执行;
  • 所有的动作算子都是急迫型(non-lazy),RDD遇到Action就会立即计算。
    (1)RDD常用动作算子:
    i.count:返回的是数据集中的元素的个数。
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.count

ii.collect:以Array返回RDD的所有元素。一般在过滤或者处理足够小的结果的时候使用。

val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.collect

iii.take:返回前n个元素。

val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.take(5)

iv.first:返回RDD第一个元素。

val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.first

v.reduce:根据指定函数,对RDD中的元素进行两两计算,返回计算结果。

val a=sc.parallelize(1 to 100)
a.reduce((x,y)=>x+y)
a.reduce(_+_)		//与上面等价
val b=sc.parallelize(Array(("A",0), ("A",2), ("B",1), ("B",2), ("C",1)))
b.reduce((x,y)=>{(x._1+y._1,x._2+y._2)})		//(AABBC,6)

vi.foreach:对RDD中的每个元素都使用指定函数,无返回值。

val rdd=sc.parallelize(1 to 100)
rdd.foreach(println)

vii.lookup:用于PairRDD,返回K对应的所有V值。

val rdd=sc.parallelize(List(('a',1), ('a',2), ('b',3), ('c',4)))
rdd.lookup('a')		//输出WrappedArray(1, 2)

viii.max min:返回最大值、最小值

val y=sc.parallelize(10 to 30)
y.max	//求最大值
y.min	//求最小值

iv.saveAsTextFile:保存RDD数据至文件系统

val rdd=sc.parallelize(1 to 10,2)
rdd.saveAsTextFile("hdfs://hadoop-master:9000/data/rddsave/")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值