一、RDD算子补充

1、mapPartitions
         mapPartitions的输入函数作用于每个分区, 也就是把每个分区中的内容作为整体来处理。   (map是把每一行)

mapPartitions一次处理一个分区的所有数据,而map算子一次处理分区中的一条数据,所以mapPartitions处理数据的速度比map快,如果RDD分区的数据很庞大,用mapPartitions容易造成内存溢出,

如果RDD分区数据量小,从而提升速度的角度考虑,可以使用mapPartitions算子。

JAVA实现:

scala实现:

2、mapPartitionsWithIndex

mapPartitionsWithIndex方法与mapPartitions方法功能类似

不同的是mapPartitionsWithIndex还会对原始分区的索引进行 追踪, 这样就能知道分区所对应的元素 。  方法的参数为一个函数, 函数的输入为整型索引和迭代器。

JAVA实现:

public static void mapPartitionsWithIndex(){
SparkConf conf=new SparkConf().setAppName("mapPartitionsWithIndex").setMaster("local");
JavaSparkContext sc=new JavaSparkContext(conf);
//模拟数据并创建初始RDD
JavaRDD<String> datas = sc.parallelize(Arrays.asList("张三","李四","李思","李斯"),2);
JavaRDD<String> result = datas.mapPartitionsWithIndex(new Function2<Integer, Iterator<String>, Iterator<String>>() { /**
*
*/
private static final long serialVersionUID = 1L; public Iterator<String> call(Integer index, Iterator<String> datass) throws Exception {
// TODO Auto-generated method stub
ArrayList<String> arrayList = new ArrayList<String>();
while(datass.hasNext()){
String info="第"+index+"分区的数据:"+datass.next();
arrayList.add(info);
}
return arrayList.iterator();
}
}, false); List<String> collect = result.collect();
for(String a:collect){
System.out.println(a);
} sc.close();
}  

scala实现:

def mapPartitionsWithIndex: Unit ={
val conf=new SparkConf().setAppName("cogroup").setMaster("local")
val sc=new SparkContext(conf)
val a=sc.parallelize(Array("liu","zhao","wang","li"),2)
val result=a.mapPartitionsWithIndex((x,y)=>{
val arraybuffer=ArrayBuffer[String]()
while(y.hasNext){
val info=x+" "+y.next()
arraybuffer+=info
}
arraybuffer.iterator
})
result.foreach(x=>{
println(x)
})
sc.stop()
}

  

3、mapValues运算

可以针对RDD内每一组(key,value)进行运算, 并且产生另外一个RDD。
           例如: 将每一组( key,value) 的value进行平方运算
           kvRDD1.mapValues(x => x*x).collect

4、union
               union方法( 等价于“++”) 是将两个RDD取并集, 取并集的过程中不 会把相同元素去掉。  union操作是输入分区与输出分区多对一模式。

scala实现:

def union: Unit ={
val conf=new SparkConf().setAppName("union").setMaster("local")
val sc=new SparkContext(conf)
val rdd1=sc.parallelize(Array((1,2),(2,3),(3,4)))
val rdd2=sc.parallelize(Array((1,2),(4,3),(5,4)))
val result=rdd1.union(rdd2)
result.foreach(x=>{
println(x._1+" "+x._2)
})
sc.stop()
}
结果:

1 2
2 3
3 4

1 2
4 3
5 4

  5、distinct
          distinct方法是将RDD中重复的元素去掉, 只留下唯一的RDD元素。

6、intersection交集运算
           intersection方法可以获取两个RDD中相同的数据

def intersection: Unit ={
val conf=new SparkConf().setAppName("intersection").setMaster("local")
val sc=new SparkContext(conf)
val rdd1=sc.parallelize(Array((1,2),(2,3),(3,4)))
val rdd2=sc.parallelize(Array((1,2),(4,3),(5,4)))
val result=rdd1.intersection(rdd2).foreach(x=>{
println(x._1+" "+x._2)})
sc.stop()
}  

7、subtract差集运算
          intRDD1.subtract(intRDD2).collect()
          intRDD1是List(3,1,2,5,5), 扣除intRDD2 List(5,6)重复的部分5, 所 以结果是(1,2,3)

//把rdd1 rdd2中的相同项,从rdd1中去除掉
def subtract: Unit ={
val conf=new SparkConf().setAppName("intersection").setMaster("local")
val sc=new SparkContext(conf)
val rdd1=sc.parallelize(Array((1,2),(2,3),(3,4)))
val rdd2=sc.parallelize(Array((1,2),(4,3),(5,4)))
rdd1.subtract(rdd2).foreach(x=>{
println(x._1+" "+x._2)})
sc.stop()
}

  8、aggregateByKey
         reduceByKey认为是aggregateByKey的简化版
         aggregateByKey最重要的一点是, 多提供了一个函数, Seq Function

可以控制如何对每个partition中的数据进行先聚合, 类似于mapreduce中的map-side combine, 然后才是对所有partition中的数据进行全局聚合
         aggregateByKey, 分为三个参数:
                    第一个参数是, 每个key的初始值
                    第二个是个函数, Seq Function, 如何进行shuffle map-side的本地聚合
                    第三个是个函数, Combiner Function, 如何进行shuffle reduce-side的全局聚合

Java实现:

scala实现:

//在调用aggregateByKey算子时,第二、三两个参数时(这两个参数传入的是函数),运用柯里化的方式,不需要给函数传参
def aggregateByKey: Unit ={
val conf=new SparkConf().setAppName("aggregateByKey").setMaster("local")
val sc=new SparkContext(conf)
val lines=sc.textFile("file:///home/hadoop/product.txt")
def seq(num1:Int,num2:Int):Int={
num1+num2
}
def comb(num1:Int,num2:Int):Int={
num1+num2
}
lines.map(x=>(x,1)).aggregateByKey(0)(seq,comb).foreach(x=>{
println(x._1+" "+x._2)
})
}

  9、cartesian
          cartesian, 中文名笛卡尔乘积
         比如说两个RDD, 分别有10条数据, 用了cartesian算子以后,两个RDD的每一条数据都会和另外一个RDD的每一条数据执行一次join,最终组成了一个笛卡尔乘积

 def cartesian: Unit ={
val conf=new SparkConf().setAppName("cartesian").setMaster("local")
val sc=new SparkContext(conf)
val rdd1=sc.parallelize(Array((1,2),(2,3),(3,4)))
val rdd2=sc.parallelize(Array((1,2),(4,3),(5,4)))
rdd1.cartesian(rdd2).foreach(x=>{
println(x._1+" "+x._2)
})
}

(1,2) (1,2)
(1,2) (4,3)
(1,2) (5,4)
(2,3) (1,2)
(2,3) (4,3)
(2,3) (5,4)
(3,4) (1,2)
(3,4) (4,3)
(3,4) (5,4)

  10、coalesce
        coalesce算子, 功能是将RDD的partition缩减, 将一定量的数据压缩到更少的partition中去。建议的使用场景, 配合filter算子使用
       使用filter算子过滤掉很多数据以后, 比如30%的数据, 出现了很多partition中的数据不均匀的情况

此时建议使用coalesce算子, 压缩rdd的partition数量, 从而让各个partition中的数 据都更加的紧凑 
       缺点:只能减少分区数,不能增加分区数

11、repartition
          repartition算子, 用于任意将rdd的partition增多或者减少

与coalesce不同之处在于, coalesce仅仅能将rdd的partition变少, 但是 repartition可以将rdd的partiton变多
         一个很经典的场景, 使用Spark SQL从hive中查询数据时  Spark SQL会根据hive对应的hdfs文件的block数量来决定加载出来的数据rdd 中有多少个partition,这里的partition数量, 是我们根本无法

设置的

有时候可能自动设置的partition数量过少, 导致我们后面的算子的运行特别慢    此时就可以在Spark SQL加载hive数据到rdd之后, 立即使用repartition算子, 将rdd的partition数量变多

def repartition: Unit ={
val conf=new SparkConf().setAppName("cartesian").setMaster("local")
val sc=new SparkContext(conf)
val a=sc.parallelize(Array("liu","zhao","wang","li","lll","aa"),3)
val result=a.coalesce(2)//通过 coalesce减少分区
// val result=a.repartition(4) 通过repartition增加 或者减少分区数
result.mapPartitionsWithIndex((x,y)=>{
val arr=ArrayBuffer[String]()
while(y.hasNext){
val info=x+" "+y.next()
arr+=info
}
arr.iterator
}).foreach(x=>println(x))
}

  

补充:1、map:一次处理分区中的一条数据

mapPartitions:一次处理分区中的所有数据

mapPartitionsWithIndex:一次处理分区中的所有数据 ,并且返回分区的索引,索引从0开始

注意:如果RDD分区中的数据体量比较大,用mapPartitions或者mapPartitionsWithIndex进行计算,有可能出现内存溢出(OOM)

如果RDD分区数据体量比较小,此时为了提高数据计算的效率,可以使用mapPartitions或mapPartitionsWithIndex进行计算

RDD 算子补充的更多相关文章

  1. RDD算子

    RDD算子 #常用Transformation(即转换,延迟加载) #通过并行化scala集合创建RDD val rdd1 = sc.parallelize(Array(1,2,3,4,5,6,7,8 ...

  2. RDD算子、RDD依赖关系

    RDD:弹性分布式数据集, 是分布式内存的一个抽象概念 RDD:1.一个分区的集合, 2.是计算每个分区的函数 ,    3.RDD之间有依赖关系 4.一个对于key-value的RDD的Partit ...

  3. spark教程(四)-SparkContext 和 RDD 算子

    SparkContext SparkContext 是在 spark 库中定义的一个类,作为 spark 库的入口点: 它表示连接到 spark,在进行 spark 操作之前必须先创建一个 Spark ...

  4. Spark性能调优-RDD算子调优篇(深度好文,面试常问,建议收藏)

    RDD算子调优 不废话,直接进入正题! 1. RDD复用 在对RDD进行算子时,要避免相同的算子和计算逻辑之下对RDD进行重复的计算,如下图所示: 对上图中的RDD计算架构进行修改,得到如下图所示的优 ...

  5. Spark中普通集合与RDD算子的sortBy()有什么区别

    分别观察一下集合与算子的sortBy()的参数列表 普通集合的sortBy() RDD算子的sortBy() 结论:普通集合的sortBy就没有false参数,也就是说只能默认的升序排. 如果需要对普 ...

  6. Spark RDD算子介绍

    Spark学习笔记总结 01. Spark基础 1. 介绍 Spark可以用于批处理.交互式查询(Spark SQL).实时流处理(Spark Streaming).机器学习(Spark MLlib) ...

  7. 大数据入门第二十二天——spark(二)RDD算子(2)与spark其它特性

    一.JdbcRDD与关系型数据库交互 虽然略显鸡肋,但这里还是记录一下(点开JdbcRDD可以看到限制比较死,基本是鸡肋.但好在我们可以通过自定义的JdbcRDD来帮助我们完成与关系型数据库的交互.这 ...

  8. 大数据入门第二十二天——spark(二)RDD算子(1)

    一.RDD概述 1.什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的 ...

  9. RDD算子的使用

    TransformationDemo.scala import org.apache.spark.{HashPartitioner, SparkConf, SparkContext} import s ...

随机推荐

  1. moment.js使用方法总结

    Moment.js是一个轻量级的JavaScript时间库,它方便了日常开发中对时间的操作,提高了开发效率.日常开发中,通常会对时间进行下面这几个操作:比如获取时间,设置时间,格式化时间,比较时间等等 ...

  2. spring cloud 入门系列七:基于Git存储的分布式配置中心--Spring Cloud Config

    我们前面接触到的spring cloud组件都是基于Netflix的组件进行实现的,这次我们来看下spring cloud 团队自己创建的一个全新项目:Spring Cloud Config.它用来为 ...

  3. 模拟IDE上的run过程

    看了一下老陈写的模仿JDK动态代理,从中取一部分单独扩展,模拟一下IDE上的run过程(不愧是老陈,去年写的东西我要现在才能理解) 对run过程的猜想 在点击run的过程中应该做了不少事.先编译运行r ...

  4. vs2017搭建linux c++开发环境

    最近一直在阅读ovs的源码,看到用户态代码的时候,需要对用户态的代码进行调试,一开始想直接使用linux中的GDB进行调试,但是ovs的工程太过于复杂,从网上找了些文章,发现vs2017能够支持lin ...

  5. Professional Books

    Machine Learning:     Pattern Recognition and Machine Learning(PRML)    https://mqshen.gitbooks.io/p ...

  6. C++进阶训练——停车收费系统设计

    一.简介 经过一段时间的c++基础学习,是时候做一个较为全面的.运用c++功能的较复杂的项目练练手了. 运用软件:Visual Studio   (VS). 题目:c++停车收费系统设计(某本编程书进 ...

  7. zookeeper的选举过程

    zookeeper的选举过程大致如下: zookeeper的选举过程,就是选出一个在n/2+1个节点中选出一个节点为主节点的过程.比如,当我们启动一个有5个节点的zookeeper集群的时候.首先启动 ...

  8. [leetcode-914-X of a Kind in a Deck of Cards]

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  9. RESTful源码笔记之RESTful Framework的基本组件

    快速实例 Quickstart 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式. ...

  10. Xftp安装和使用的视频录制方法

    内容: 1.使用工具 2.操作步骤及方法 视频地址: http://v.youku.com/v_show/id_XMzEwNjg2MTg2NA==.html?spm=a2h3j.8428770.341 ...