1、使用MapPartitions代替map

  1.1 为什么要死使用MapPartitions代替map

    普通的map,每条数据都会传入function中进行计算一次;而是用MapPartitions时,function会一次接受所有partition的数据出入到function中计算一次,性能较高。

    但是如果内存不足时,使用MapPartitions,一次将所有的partition数据传入,可能会发生OOM异常

  1.2 如何使用

    有map的操作的地方,都可以使用MapPartitions进行替换

        /**
* 使用mapPartitionsToPair代替mapToPair
*/
JavaPairRDD<String, Row> sessionRowPairRdd =dateRangeRdd.mapPartitionsToPair(new PairFlatMapFunction<Iterator<Row>, String, Row>() { private static final long serialVersionUID = 1L; public Iterable<Tuple2<String, Row>> call(Iterator<Row> rows) throws Exception {
List<Tuple2<String, Row>> list=new ArrayList<Tuple2<String, Row>>();
while (rows.hasNext()) {
Row row=rows.next();
list.add(new Tuple2<String, Row>(row.getString(), row));
}
return list;
}
}); /*JavaPairRDD<String, Row> sessionRowPairRdd = dateRangeRdd
.mapToPair(new PairFunction<Row, String, Row>() { private static final long serialVersionUID = 1L;
// 先将数据映射为<sessionId,row>
public Tuple2<String, Row> call(Row row) throws Exception {
return new Tuple2<String, Row>(row.getString(2), row);
}
});*/

2、使用coalesce对过滤后的Rdd进行重新分区和压缩

  2.1 为什么使用coalesce

    默认情况下,经过过滤后的数据的分区数和原分区数是一样的,这就导致过滤后各个分区中的数据可能差距很大,在之后的操作中造成数据倾斜

    使用coalesce可以使过滤后的Rdd的分区数减少,并让每个分区中的数据趋于平等

  2.2 如何使用   

       //过滤符合要求的ClickCategoryIdRow    
    filteredSessionRdd.filter(new Function<Tuple2<String,Row>, Boolean>() {
private static final long serialVersionUID = 1L;
public Boolean call(Tuple2<String, Row> tuple2) throws Exception {
return (Long.valueOf(tuple2._2.getLong())!=null)?true:false;
}
})
//使用coalesce将过滤后的数据重新分区和压缩,时新的分区中的数据大致相等
.coalesce()

3、使用foreachPartition替代foreach

  3.1 为什么使用foreachPartition

    默认使用的foreach,每条数据都会传入function进行计算;如果操作数据库,每条数据都会获取一个数据库连接并发送sql进行保存,消耗资源比较大,性能低。

    使用foreachPartition,会把所用partition的数据一次出入function,只需要获取一次数据库连接,性能高。

  3.2 如何使用

        /**
* 使用foreachPartition替代foreach
*/
sessionRdd.join(sessionRowPairRdd).foreachPartition(new VoidFunction<Iterator<Tuple2<String,Tuple2<String,Row>>>>() {
private static final long serialVersionUID = 1L;
public void call(Iterator<Tuple2<String, Tuple2<String, Row>>> iterator)
throws Exception {
List<SessionDetail> sessionDetails=new ArrayList<SessionDetail>();
if (iterator.hasNext()) {
Tuple2<String, Tuple2<String, Row>> tuple2=iterator.next();
String sessionId=tuple2._1;
Row row=tuple2._2._2;
SessionDetail sessionDetail=new SessionDetail();
sessionDetail.setSessionId(sessionId);
sessionDetail.setTaskId((int)taskId);
sessionDetail.setUserId((int)row.getLong());
sessionDetails.add(sessionDetail);
}
DaoFactory.getSessionDetailDao().batchInsertSessionDao(sessionDetails);
}
}); /* sessionRdd.join(sessionRowPairRdd).foreach(new VoidFunction<Tuple2<String,Tuple2<String,Row>>>() {
private static final long serialVersionUID = 1L;
public void call(Tuple2<String, Tuple2<String, Row>> tuple2) throws Exception {
String sessionId=tuple2._1;
Row row=tuple2._2._2;
SessionDetail sessionDetail=new SessionDetail();
sessionDetail.setSessionId(sessionId);
sessionDetail.setTaskId((int)taskId);
sessionDetail.setUserId((int)row.getLong(1));
  DaoFactory.getSessionDetailDao().insertSessionDao(sessionDetail);
}
});*/

4、使用repartition进行调整并行度

  4.1 为什么要使用repartition

    spark.default.parallelism设置的并行度只能对没有Spark SQL(DataFrame)的阶段有用,对Spark SQL的并行度是无法设置的,该并行度是通过hdfs文件所在的block块决定的。

    可以通过repartition调整之后的并行度

  4.2 如何使用 

sqlContext.sql("select * from user_visit_action where date >= '" + startDate + "' and date <= '" + endDate + "'").javaRDD()
//使用repartition调整并行度
.repartition()

5、使用reduceByKey进行本地聚合

  5.1 reduceByKey有哪些优点

    reduceByKey相对于普通的shuffle操作(如groupByKey)的一个最大的优点,会进行map端的本地聚合,从而减少文件的输出,减少磁盘IO,网络传输,内存占比以及reduce端的聚合操作数据。

  5.2 使用场景

    只有是针对每个不同的key进行相应的操作都可以使用reduceByKey进行处理

spark性能调优04-算子调优的更多相关文章

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

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

  2. Spark性能优化:数据倾斜调优

    前言 继<Spark性能优化:开发调优篇>和<Spark性能优化:资源调优篇>讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化 ...

  3. 【转】Spark性能优化指南——基础篇

    http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=2651805828&idx=1&sn=2f413828d1fdc6a ...

  4. spark性能调优:资源优化

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

  5. Spark性能调优之代码方面的优化

    Spark性能调优之代码方面的优化 1.避免创建重复的RDD     对性能没有问题,但会造成代码混乱   2.尽可能复用同一个RDD,减少产生RDD的个数   3.对多次使用的RDD进行持久化(ca ...

  6. (转)Spark性能优化:资源调优篇

      在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何 ...

  7. [Spark性能调优] 第一章:性能调优的本质、Spark资源使用原理和调优要点分析

    本課主題 大数据性能调优的本质 Spark 性能调优要点分析 Spark 资源使用原理流程 Spark 资源调优最佳实战 Spark 更高性能的算子 引言 我们谈大数据性能调优,到底在谈什么,它的本质 ...

  8. [Spark性能调优] 第二章:彻底解密Spark的HashShuffle

    本課主題 Shuffle 是分布式系统的天敌 Spark HashShuffle介绍 Spark Consolidated HashShuffle介绍 Shuffle 是如何成为 Spark 性能杀手 ...

  9. Spark性能调优之合理设置并行度

    Spark性能调优之合理设置并行度 1.Spark的并行度指的是什么?     spark作业中,各个stage的task的数量,也就代表了spark作业在各个阶段stage的并行度!     当分配 ...

  10. Spark性能调优之解决数据倾斜

    Spark性能调优之解决数据倾斜 数据倾斜七种解决方案 shuffle的过程最容易引起数据倾斜 1.使用Hive ETL预处理数据    • 方案适用场景:如果导致数据倾斜的是Hive表.如果该Hiv ...

随机推荐

  1. 【Nacos】数据一致性

    转自:https://blog.csdn.net/liyanan21/article/details/89320872 目录 一.Raft算法 二.Nacos中Raft部分源码 init() 1. 获 ...

  2. 本地存储(sessionStrorage,localStorage)

    1.本地存储特性 1. 数据存储在用户浏览器中 2. 设置,读取方便,设置页面刷新不丢失数据 3. 容量较大,sessionStorage约5M,localStorage约20M 4. 只能存储字符串 ...

  3. layui修改表格行高

    .layui-table-cell { height: auto !important; white-space: normal; }

  4. 2018-8-10-win10-uwp-httpClient-登陆CSDN

    title author date CreateTime categories win10 uwp httpClient 登陆CSDN lindexi 2018-08-10 19:16:53 +080 ...

  5. thinkphp5 自动注册Hook机制钩子扩展

    Hook.php 文件已更新1.修复在linux环境下类的 \ 在basename 下无法获取到类名的问题2.修复linux 环境下无法使用hook::call 调用失败问题 请先安装thinkphp ...

  6. jQuery JCrop插件的使用详解

    jQuery的一个图片剪切的一个插件, 使用插件必须条件:引入jQuery.js文件,引入jQuery.Jcrop.js文件,引入JQuery.Jcrop.css文件   1.最基本的使用方法: &l ...

  7. springmvc.xml标配配置

    这里提供配置模板[绝不会多余]: <context:component-scan base-package="com.atguigu"></context:com ...

  8. js变量var与let的区别

    1.作用域 通过var定义的变量,作用域是整个封闭函数,是全域的 .通过let定义的变量,作用域是在块级或是子块中. for (let i = 0; i < 10; i++) { // ... ...

  9. RAM/ROM IP一次性总结

    1, 若需要修改memory mode, 需重新编译; 若不需要修改memory mode, 直接修改宏参数即可; 2, 宏参数列表: 3, 注意用LE搭memory的情况; 4, memory ty ...

  10. shell 输入输出重定向

    1. 命令列表: command > file 将输出重定向到file command < file 将输入重定向到file command >> file 将输出以追加的方式 ...