RDD 算子补充
一、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 算子补充的更多相关文章
- RDD算子
RDD算子 #常用Transformation(即转换,延迟加载) #通过并行化scala集合创建RDD val rdd1 = sc.parallelize(Array(1,2,3,4,5,6,7,8 ...
- RDD算子、RDD依赖关系
RDD:弹性分布式数据集, 是分布式内存的一个抽象概念 RDD:1.一个分区的集合, 2.是计算每个分区的函数 , 3.RDD之间有依赖关系 4.一个对于key-value的RDD的Partit ...
- spark教程(四)-SparkContext 和 RDD 算子
SparkContext SparkContext 是在 spark 库中定义的一个类,作为 spark 库的入口点: 它表示连接到 spark,在进行 spark 操作之前必须先创建一个 Spark ...
- Spark性能调优-RDD算子调优篇(深度好文,面试常问,建议收藏)
RDD算子调优 不废话,直接进入正题! 1. RDD复用 在对RDD进行算子时,要避免相同的算子和计算逻辑之下对RDD进行重复的计算,如下图所示: 对上图中的RDD计算架构进行修改,得到如下图所示的优 ...
- Spark中普通集合与RDD算子的sortBy()有什么区别
分别观察一下集合与算子的sortBy()的参数列表 普通集合的sortBy() RDD算子的sortBy() 结论:普通集合的sortBy就没有false参数,也就是说只能默认的升序排. 如果需要对普 ...
- Spark RDD算子介绍
Spark学习笔记总结 01. Spark基础 1. 介绍 Spark可以用于批处理.交互式查询(Spark SQL).实时流处理(Spark Streaming).机器学习(Spark MLlib) ...
- 大数据入门第二十二天——spark(二)RDD算子(2)与spark其它特性
一.JdbcRDD与关系型数据库交互 虽然略显鸡肋,但这里还是记录一下(点开JdbcRDD可以看到限制比较死,基本是鸡肋.但好在我们可以通过自定义的JdbcRDD来帮助我们完成与关系型数据库的交互.这 ...
- 大数据入门第二十二天——spark(二)RDD算子(1)
一.RDD概述 1.什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的 ...
- RDD算子的使用
TransformationDemo.scala import org.apache.spark.{HashPartitioner, SparkConf, SparkContext} import s ...
随机推荐
- Windows下Mongodb安装部署
1.下载安装包 mongodb-win32-x86_64-enterprise-windows-64-3.6.4.zip 解压 安装失败(当前环境windows server2012 R2):已验证可 ...
- Winrar去广告图文教程
一.前言 1.1 Winrar 解压缩工具 市场上有很多优秀的压缩工具,常用的有Winrar 和360 压缩工具.Winrar是免费压缩工具,特色是每次使用都会弹出广告.影响用户体验和工作效率,当然最 ...
- openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 四
openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...
- linux同步软件
linux同步软件:scp,rsync,inotify,sersync 1.scp: scp就是secure copy,是用来进行远程文件拷贝的.数据传输使用 ssh,并且和ssh 使用相同的认证方式 ...
- 第四次ScrumMeeting博客
第四次ScrumMeeting博客 本次会议于10月28日(六)22时整在3公寓725房间召开,持续15分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕. 1. 每个人的工作(有Issue的内容和 ...
- 20个常用Linux性能监控工具/命令
20个常用Linux性能监控工具/命令 对于 Linux/Unix 系统管理员非常有用的并且最常用的20个命令行系统监视工具.这些命令可以在所有版本的 Linux 下使用去监控和查找系统性能的实际原因 ...
- 【探路者】互评beta版本
成员博客 1蔺依铭:http://www.cnblogs.com/linym762/ 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http://www.cnblogs ...
- struts-resultType属性
1.默认dispatcher:forward方式,服务器端跳转 2.redirect:客户端跳转 3.chain:Action转发,forward方式,服务器端跳转action 4.redirectA ...
- css全局样式基础代码
body{ font-size:12px; font-family:"宋体",Arial, Helvetica, sans-serif;color:#363636;backgrou ...
- lintcode-198-排列序号II
198-排列序号II 给出一个可能包含重复数字的排列,求这些数字的所有排列按字典序排序后该排列在其中的编号.编号从1开始. 样例 给出排列[1, 4, 2, 2],其编号为3. 思路 和 lintco ...