一、对多次使用的RDD进行持久化

  如何选择一种最合适的持久化策略?

   默认情况下,性能最高的当然是MEMORY_ONLY,但前提是你的内存必须足够足够大, 可以绰绰有余地存放下整个RDD的所有数据。因为不进行序列化与反序列化操作,就避 免了这部分的性能开销;对这个RDD的后续算子操作,都是基于纯内存中的数据的操作 ,不需要从磁盘文件中读取数据,性能也很高;而且不需要复制一份数据副本,并远程传 送到其他节点上。但是这里必须要注意的是,在实际的生产环境中,恐怕能够直接用这种 策略的场景还是有限的,如果RDD中数据比较多时(比如几十亿),直接用这种持久化 级别,会导致JVM的OOM内存溢出异常。

  如果使用MEMORY_ONLY级别时发生了内存溢出,那么建议尝试使用 MEMORY_ONLY_SER级别。该级别会将RDD数据序列化后再保存在内存中,此时每个 partition仅仅是一个字节数组而已,大大减少了对象数量,并降低了内存占用。这种级别 比MEMORY_ONLY多出来的性能开销,主要就是序列化与反序列化的开销。但是后续算 子可以基于纯内存进行操作,因此性能总体还是比较高的。此外,可能发生的问题同上, 如果RDD中的数据量过多的话,还是可能会导致OOM内存溢出的异常。

  如果纯内存的级别都无法使用,那么建议使用MEMORY_AND_DISK_SER策略,而不是 MEMORY_AND_DISK策略。因为既然到了这一步,就说明RDD的数据量很大,内存无法完全放下。序列化后的数据比较少,可以节省内存和磁盘的空间开销。同时该策略会优先尽量尝试将数据缓存在内存中,内存缓存不下才会写入磁盘。

  通常不建议使用DISK_ONLY和后缀为_2的级别:因为完全基于磁盘文件进行数据的读写 ,会导致性能急剧降低,有时还不如重新计算一次所有RDD。后缀为_2的级别,必须将 所有数据都复制一份副本,并发送到其他节点上,数据复制以及网络传输会导致较大的性 能开销,除非是要求作业的高可用性,否则不建议使用。

二、广播大变量

  开发过程中,会遇到需要在算子函数中使用外部变量的场景(尤其是大变量,比如 100M以上的大集合),那么此时就应该使用Spark的广播(Broadcast)功能来提 升性能

  函数中使用到外部变量时,默认情况下,Spark会将该变量复制多个副本,通过网络 传输到task中,此时每个task都有一个变量副本。如果变量本身比较大的话(比如 100M,甚至1G),那么大量的变量副本在网络中传输的性能开销,以及在各个节 点的Executor中占用过多内存导致的频繁GC(垃圾回收),都会极大地影响性能

  如果使用的外部变量比较大,建议使用Spark的广播功能,对该变量进行广播。广播 后的变量,会保证每个Executor的内存中,只驻留一份变量副本,而Executor中的 task执行时共享该Executor中的那份变量副本。这样的话,可以大大减少变量副本 的数量,从而减少网络传输的性能开销,并减少对Executor内存的占用开销,降低 GC的频率

  广播大变量发送方式:Executor一开始并没有广播变量,而是task运行需要用到广 播变量,会找executor的blockManager要,bloackManager找Driver里面的 blockManagerMaster要。

三、使用Kryo优化序列化性能

  在Spark中,主要有三个地方涉及到了序列化:

    在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输

    将自定义的类型作为RDD的泛型类型时(比如JavaRDD,SXT是自定义类型),所有自 定义类型对象,都会进行序列化。因此这种情况下,也要求自定义的类必须实现 Serializable接口。

    使用可序列化的持久化策略时(比如MEMORY_ONLY_SER),Spark会将RDD中的每个 partition都序列化成一个大的字节数组。

  Spark支持使用Kryo序列化机制。Kryo序列化机制,比默认的Java序列化机制,速度要快 ,序列化后的数据要更小,大概是Java序列化机制的1/10。所以Kryo序列化优化以后,可 以让网络传输的数据变少;在集群中耗费的内存资源大大减少。

  对于这三种出现序列化的地方,我们都可以通过使用Kryo序列化类库,来优化序列化和 反序列化的性能。

  Spark默认使用的是Java的序列化机制,也就是 ObjectOutputStream/ObjectInputStream API来进行序列化和反序列化。但是Spark同 时支持使用Kryo序列化库,Kryo序列化类库的性能比Java序列化类库的性能要高很多。

   官方介绍,Kryo序列化机制比Java序列化机制,性能高10倍左右。Spark之所以默认没有 使用Kryo作为序列化类库,是因为Kryo要求最好要注册所有需要进行序列化的自定义类 型,因此对于开发者来说,这种方式比较麻烦

四、优化数据结构

  Java中,有三种类型比较耗费内存:

    对象,每个Java对象都有对象头、引用等额外的信息,因此比较占用内存空间。

    字符串,每个字符串内部都有一个字符数组以及长度等额外信息。 集合类型,比如HashMap、LinkedList等,因为集合类型内部通常会使用一些内部类来 封装集合元素,比如Map.Entry。

    因此Spark官方建议,在Spark编码实现中,特别是对于算子函数中的代码,尽 量不要使用上述三种数据结构,尽量使用字符串替代对象,使用原始类型(比如 Int、Long)替代字符串,使用数组替代集合类型,这样尽可能地减少内存占用 ,从而降低GC频率,提升性能。

Spark调优(一)的更多相关文章

  1. 【Spark学习】Apache Spark调优

    Spark版本:1.1.0 本文系以开源中国社区的译文为基础,结合官方文档翻译修订而来,转载请注明以下链接: http://www.cnblogs.com/zhangningbo/p/4117981. ...

  2. 【Spark调优】提交job资源参数调优

    [场景] Spark提交作业job的时候要指定该job可以使用的CPU.内存等资源参数,生产环境中,任务资源分配不足会导致该job执行中断.失败等问题,所以对Spark的job资源参数分配调优非常重要 ...

  3. 【Spark调优】大表join大表,少数key导致数据倾斜解决方案

    [使用场景] 两个RDD进行join的时候,如果数据量都比较大,那么此时可以sample看下两个RDD中的key分布情况.如果出现数据倾斜,是因为其中某一个RDD中的少数几个key的数据量过大,而另一 ...

  4. 【Spark调优】小表join大表数据倾斜解决方案

    [使用场景] 对RDD使用join类操作,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD或表的数据量比较小(例如几百MB或者1~2GB),比较适用此方案. [解决方案] ...

  5. 【Spark调优】数据倾斜及排查

    [数据倾斜及调优概述] 大数据分布式计算中一个常见的棘手问题——数据倾斜: 在进行shuffle的时候,必须将各个节点上相同的key拉取到某个节点上的一个task来进行处理,比如按照key进行聚合或j ...

  6. 【Spark调优】Broadcast广播变量

    [业务场景] 在Spark的统计开发过程中,肯定会遇到类似小维表join大业务表的场景,或者需要在算子函数中使用外部变量的场景(尤其是大变量,比如100M以上的大集合),那么此时应该使用Spark的广 ...

  7. 【Spark调优】Kryo序列化

    [Java序列化与反序列化] Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程.序列化使用场景:1.数据的持久化,通过序列化可以把数据永久 ...

  8. 【翻译】Spark 调优 (Tuning Spark) 中文版

    由于Spark自己的调优guidance已经覆盖了很多很有价值的点,因此这里直接翻译一份过来.也作为一个积累. Spark 调优 (Tuning Spark) 由于大多数Spark计算任务是在内存中运 ...

  9. 【Spark调优】Shuffle原理理解与参数调优

    [生产实践经验] 生产实践中的切身体会是:影响Spark性能的大BOSS就是shuffle,抓住并解决shuffle这个主要原因,事半功倍. [Shuffle原理学习笔记] 1.未经优化的HashSh ...

  10. 【Spark调优】:结合业务场景,优选高性能算子

    聚合操作使用reduceByKey/aggregateByKey替代groupByKey 参见我的这篇博客说明 [Spark调优]:如果实在要shuffle,使用map侧预聚合的算子 内存充足前提下使 ...

随机推荐

  1. 字符串NSString与NSMutableString常用方法

    NSString 1.初始化 NSString *str1 = @"a OC Program"; 2.初始化 NSString *str2 = [[NSString alloc] ...

  2. Day3-C-Radar Installation POJ1328

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. ...

  3. 「NOIP2011」Mayan游戏

    传送门 Luogu 解题思路 爆搜,并考虑几个剪枝. 不交换颜色相同的方块(有争议,但是可以过联赛数据 \(Q \omega Q\)) 左边为空才往左换 右边不为空才往右换 因为对于两个相邻方块,右边 ...

  4. 099、Java中String类之字符数组与字符串的转换

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  5. LVS负载均衡基本原理

    负载均衡基本原理与lvs 基本介绍 1.1 负载均衡的由来 在业务初期,我们一般会先使用单台服务器对外提供服务.随着业务流量越来越大,单台服务器无论如何优化,无论采用多好的硬件,总会有性能天花板,当单 ...

  6. activity标题栏和状态栏操作

    修改显示的标题 1.修改AndroidMainfest.xml文件的label标签 2.setTitle("标签"); 去掉标签的显示 1.android:theme=" ...

  7. HTML学习第六天

    HTML学习第六天 一.全局属性 contentEditable属性,控制标签元素的可修改性,默认与“”(空字符串)都代表真,即可编辑 <!DOCTYPE html> <html l ...

  8. fuseki远程访问方法

    ./fuseki-server启动服务后,我们的服务只能是localhost访问,无法被其他人访问,那么 要怎么修改呢.很简单,把apche-jena-fuseki-3.10.0/run 下面的shi ...

  9. Readiness 探测【转】

    除了 Liveness 探测,Kubernetes Health Check 机制还包括 Readiness 探测. 用户通过 Liveness 探测可以告诉 Kubernetes 什么时候通过重启容 ...

  10. vue+element 递归上传图片

    直接上代码. <template>   <div>     <el-upload       action="http://localhost:3000/pic ...