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. ConcurrentHashMap(锁分段技术)

    线程不安全的HashMap     因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap.   效率低下的HashTab ...

  2. python实现发送文本邮件

    简单实现了python发送文本邮件 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/4/25 17:09 # @Author ...

  3. 力扣 ——Remove Duplicates from Sorted List II(删除排序链表中的重复元素 II)python实现

    题目描述: 中文: 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 1: 输入: 1->2->3->3->4->4-> ...

  4. Java使用SSH远程访问Windows并执行命令

    转载于:http://blog.csdn.net/carolzhang8406/article/details/6760430   https://blog.csdn.net/angel_xiaa/a ...

  5. proxy汇总-1

    1.apt-get的proxy 新建/etc/apt/apt.conf.d目录下新建10proxy文件,添加: Acquire::http::proxy"http://xx.xx.xx.xx ...

  6. Python执行和拷贝

    import paramiko from scp import SCPClient class LinuxSSHSCP(object): def __init__(self, ip, username ...

  7. youlexuan父类配置

    <!-- 集中定义依赖版本号 -->    <properties>        <junit.version>4.12</junit.version> ...

  8. 【基础】Maven生命周期

    Maven是一个优秀的项目管理工具,它能够帮你管理编译.报告.文档等. Maven的生命周期: maven的生命周期是抽象的,它本身并不做任何的工作.实际的工作都交由"插件"来完成 ...

  9. 基于CentOS 7.3 安装Ceph Jewel 10.2.9

    https://www.lijiawang.org/posts/intsall-ceph.html 配置说明: 采用了4台centos7.3系统的虚拟机,1台Ceph-Master作为安装节点,NTP ...

  10. windows 下安装python 的requests模块

    下载地址:https://codeload.github.com/requests/requests/legacy.zip/master 下载好后解压,进入目录执行下面命令 在cmd下:python ...