spark编程基本(二)-- RDD编程

本文介绍了Spark中的RDD编程,包括从文件和并行集合创建RDD、RDD的操作如转换和行动操作,以及持久化策略。重点讲解了reduceByKey、groupByKey的区别,并讨论了分区原则和Pair RDD的常用操作。此外,还提到了广播变量和累加器这两种共享变量的使用。
摘要由CSDN通过智能技术生成

RDD创建

从文件系统中加载数据创建RDD:

  1. Spark采用textFile() 方法来从文件系统中加载数据创建RDD

  2. 方法把文件的URI作为参数,这个URI可以是:

     1) 本地文件系统的地址
     2) 或者是分布式文件系统HDFS的地址
     3) 或者是Amazon S3的地址等
    

通过并行集合(数组)创建RDD:
可以调用SparkContext的parallelize方法,在Driver中一个已经存在的集合(数组)上创建。

val array = Array(1,2,3,4,5)
val rdd = sc.parallelize(array)

RDD操作

转换操作

  1. 对于RDD而言,每一个转换操作都会产生不同的RDD,供一个操作使用。
  2. 转换到的RDD是惰性求值的。不发生真正的计算。

基本的转化操作

函数名 目的
map() 将函数应用于RDD中的每个元素,将返回值构成新的RDD
flatmap() 将函数应用于RDD中的每个元素,将返回的迭代器的内容构成新的RDD,通常用来切分单词
filter() 返回一个通过传给filter()的函数的元素组成RDD
distinct() 去重
sample(withReplacement, fraction, [seed] 对RDD采样,以及是否替换
union() 生成一个包含两个RDD中所有元素的RDD
intersection() 求两个RDD共同的元素的RDD
subtract() 移除一个RDD中的内容
cartesian() 于另一个RDD的笛卡尔积
groupByKey 应用于(K, b)键值对的数据集时,返回一个新的(K, Iterable)形式的数据集
reduceByKey(func) 应用于(K, V)键值对的数据集时,返回一个新的(K, V)形式的数据集,其中的每个值是将每个Key传递到函数func中进行聚合

行动操作

真正触发计算的地方。

函数名 目的
collect() 返回RDD中的所有元素
count() RDD中的元素个数
countByValue() 各元素在RDD中出现的次数
take(num) 从RDD中返回num个元素
top(num) 从RDD中返回最前面的num个元素
takeOrdered(num) (ordering) 从RDD中按照提供的顺序返回最前面的num个元素
takeSample(withRepalcement, num, [seed]) 从RDD中返回任意一些元素
reduce(func) 并行整合RDD中所有的整数
fold(zero)(func) 和reduce()一样,但是需要提供初始值
aggreagte(zeroValue)(seqOp, comOp) 和Reduce()相似,但是通常返回不同类型的函数
foreach(func) 对RDD中的每个元素使用给定的函数

注意点:

  • collect() 要求所有数据都必须能一同放入单台机器的内存中。
  • take(n) 尝试只访问尽量少的分区,因此会得到一个不均衡的集合,返回元素的顺序与预期不一致。
  • top() 可以通过提供自己的比较函数,来提取前几个元素
  • foreach() 不将任何结果返回到驱动程序中,把数据发送到一个网络服务器中或数据库中。

持久化

spark中,RDD采用惰性求值得机制,每次遇到行动操作,都会从头开始执行计算,每次调用行动操作,都会触发一次从头开始的计算,这对于迭代操作而言,代价是很大的,迭代计算经常需要多次重复使用同一组数据。

可以通过持久化(缓存)机制避免这种重复计算的开销。
可以使用persist()方法对一个RDD标记为持久化。

persist()的圆括号内中包含的是持久化级别参数。

  • persist(MEMORY_ONLY):表示将RDD作为反序列化的对象存储于JVM中,如果内存不足,就要按照LRU原则替换缓存中的内存。
  • persist(MEMORY_AND_DISK)表示将RDD作为反序列化的对象存储在JVM中,如果内存不足,超出的分区将会被存放在硬盘上。
  • 可以使用unpersist()方法手动地把持久化的RDD从缓存中移除。
  • 一般而言,使用cache()方法时,会调用persist(MEMORY_ONLY)

分区

分区原则:
RDD分区的一个分区原则是使得分区的个数尽量等于集群中的CPU核心数目。

默认分区数目:
对于不同的Spark部署模式而言,都可以通过设置spark.default.parallelism这个参数的值,来配置默认的分区数目。

手动设置分区:

  1. 创建RDD时:在调用textFile和parallelize方法时候手动指定分区个数,sc.textFile(path, partitionNum)
  2. 通过转换操作得到RDD时:直接调用repatition方法即可(RDD数据量在经过转换操作后变小,无需过多的分区)

打印元素:

  • 单机模式下打印输出到屏幕上:rdd.foreach(println)或rdd.map(println)
  • 为了能够把所有worker节点上的打印输出信息也显示到Driver Program中,可以使用collect()方法:rdd.collect().foreach(println)。但是如果数据量过大,可能会导致内存溢出,采用rdd.take(100).foreach(println)。

Pair RDD的创建

从文件中加载

使用map()函数创建:

val lines = sc.textFile("file:///usr/local/spark/mycode/pairrdd/word.txt")

val pairRDD = lines.flatMap(line => line.split(" ").map(word => (word.1))

pairRDD.foreach(println)

通过并行集合(数组)创建RDD

val list = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值