RDD编程模型笔记(一)

1.RDD编程模型

  • 在 Spark 中,RDD 被表示为对象,通过对象上的方法调用来对 RDD 进行转换。 在Spark中,只有遇到action,才会执行

  • RDD 的计算(即延迟计算),这样在运行时可以通过管道的方式传输多个转换。

2.RDD的创建

在 Spark 中创建 RDD 的方式可以分为 3 种:

  • 从集合中创建RDD
  • 从外部存储创建RDD
  • 从其他RDD转换得到新的RDD
2.1 从集合中创建RDD
  1. 使用parallelize函数创建

    scala> val arr = Array(10,20,30,40,50,60)
    arr: Array[Int] = Array(10, 20, 30, 40, 50, 60)

    scala> val rdd1 = sc.parallelize(arr)
    rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at :26

  2. 使用makeRDD函数创建

    scala> val arr2 = sc.makeRDD(Array(10,20,30,40,50,60))
    arr2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[1] at makeRDD at :24

说明

  • 一旦RDD创建成功,就可以通过并行的方式去操作这个分布式的数据集。
  • parallelize和makeRDD还有一个重要的参数就是把数据集切分成分区数
  • Spark会为每一个分区运行一个Task,而且会自动根据你的集群来设置分区数
2.2 从外部存储创建RDD

Spark 也可以从任意 Hadoop 支持的存储数据源来创建分布式数据集。可以是本地文件系统, HDFS, Cassandra, HVase, Amazon S3 等等。Spark 支持 文本文件, SequenceFiles, 和其他所有的 Hadoop InputFormat。

scala> var distFile = sc.textFile("words.txt")
distFile: org.apache.spark.rdd.RDD[String] = words.txt MapPartitionsRDD[1] at textFile at <console>:24

scala> distFile.collect
res0: Array[String] = Array(hello world, hello atguigu, hello spark, "hello ", scala, programming)
2.3 从其他RDD转换得到新的RDD

也就是通过RDD的各种转换算子来得到新的RDD

3. RDD的转换

在RDD上支持2种操作

  • transformation,从一个已知的RDD中创建一个新的RDD
  • action,在数据集上计算结束之后,给驱动程序返回一个值
    在 Spark 中几乎所有的transformation操作都是懒执行的(lazy), 也就是说transformation操作并不会立即计算他们的结果, 而是记住了这个操作。
  • Value类型
  • Key-Value类型
3.1 Value类型1

map(func)

作用: 返回一个新的 RDD, 该 RDD 是由原 RDD 的每个元素经过函数转换后的值而组成. 就是对 RDD 中的数据做转换.

案例:创建一个包含1-10的的 RDD,然后将每个元素*2形成新的 RDD

scala> val rdd1 = sc.parallelize(1 to 10)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[2] at parallelize at <console>:24

scala> val rdd2 = rdd1.map(_ * 2)
rdd2: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[3] at map at <console>:26

scala> rdd2.collect
res1: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

mapPartitionsWithIndex(func)

作用: 和mapPartitions(func)类似. 但是会给func多提供一个Int值来表示分区的索引.
所以func的类型是:(Int, Iterator) => Iterator

scala> val rdd1 = sc.parallelize(Array(10,20,30,40,50,60))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at <console>:24

scala> rdd1.mapPartitionsWithIndex((index, items) => items.map((index, _)))
res5: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[7] at mapPartitionsWithIndex at <console>:27
scala> res5.collect
res6: Array[(Int, Int)] = Array((0,10), (1,20), (1,30), (2,40), (3,50), (3,60))

flatMap(func)

作用: 类似于map,但是每一个输入元素可以被映射为 0 或多个输出元素(所以func应该返回一个序列,而不是单一元素 T =>
TraversableOnce[U])

案例:创建一个元素为 1-5 的RDD,运用 flatMap创建一个新的 RDD,新的 RDD 为原 RDD 每个元素的 平方和三次方 来组成 1,1,4,8,9,27…

scala> val rdd1 = sc.parallelize(Array(1,2,3,4,5))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala>  rdd1.flatMap(x => Array(x * x, x * x * x))
res7: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[9] at flatMap at <console>:27

scala> res7.collect
res8: Array[Int] = Array(1, 1, 4, 8, 9, 27, 16, 64, 25, 125)

map()和mapPartition()的区别:

  1. map():每次处理一条数据。
  2. mapPartition():每次处理一个分区的数据,这个分区的数据处理完后,原 RDD 中该分区的数据才能释放,可能导致 OOM。
  3. 开发指导:当内存空间较大的时候建议使用mapPartition(),以提高处理效率。

glom()

作用: 将每一个分区的元素合并成一个数组,形成新的 RDD 类型是RDD[Array[T]]

案例:创建一个 4 个分区的 RDD&

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值