概叙:

在任何分布式系统中,序列化都是扮演着一个重要的角色的。如果使用的序列化技术,在执行序列化操作的时候很慢,或者是序列化后的数据还是很大,那么会让分布式应用程序的性能下降很多。所以,进行Spark性能优化的第一步,就是进行序列化的性能优化。

Spark自身默认就会在一些地方对数据进行序列化,比如Shuffle。还有就是,如果我们的算子函数使用到了外部的数据(比如Java内置类型,或者自定义类型),那么也需要让其可序列化。

而Spark自身对于序列化的便捷性和性能进行了一个取舍和权衡。默认,Spark倾向于序列化的便捷性,使用了Java自身提供的序列化机制——基于ObjectInputStream和ObjectOutputStream的序列化机制。因为这种方式是Java原生提供的,很方便使用。

但是问题是,Java序列化机制的性能并不高。序列化的速度相对较慢,而且序列化以后的数据,还是相对来说比较大,还是比较占用内存空间。因此,如果你的Spark应用程序对内存很敏感,那么,实际上默认的Java序列化机制并不是最好的选择。

spark的两种序列化机制:

Spark实际上提供了两种序列化机制,它只是默认使用了第一种:

1、Java序列化机制:默认情况下,Spark使用Java自身的ObjectInputStream和ObjectOutputStream机制进行对象的序列化。只要你的类实现了Serializable接口,那么都是可以序列化的。而且Java序列化机制是提供了自定义序列化支持的,只要你实现Externalizable接口即可实现自己的更高性能的序列化算法。Java序列化机制的速度比较慢,而且序列化后的数据占用的内存空间比较大。

2、Kryo序列化机制:Spark也支持使用Kryo类库来进行序列化。Kryo序列化机制比Java序列化机制更快,而且序列化后的数据占用的空间更小,通常比Java序列化的数据占用的空间要小10倍。Kryo序列化机制之所以不是默认序列化机制的原因是,有些类型虽然实现了Seriralizable接口,但是它也不一定能够进行序列化;此外,如果你要得到最佳的性能,Kryo还要求你在Spark应用程序中,对所有你需要序列化的类型都进行注册。

Kryo序列化的使用:

如果要使用Kryo序列化机制,首先要用SparkConf设置一个参数,使用new SparkConf().set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")即可,即将Spark的序列化器设置为KryoSerializer。这样,Spark在内部的一些操作,比如Shuffle,进行序列化时,就会使用Kryo类库进行高性能、快速、更低内存占用量的序列化了。

使用Kryo时,它要求是需要序列化的类,是要预先进行注册的,以获得最佳性能——如果不注册的话,那么Kryo必须时刻保存类型的全限定名,反而占用不少内存。Spark默认是对Scala中常用的类型自动注册了Kryo的,都在AllScalaRegistry类中。

但是,比如自己的算子中,使用了外部的自定义类型的对象,那么还是需要将其进行注册。

(实际上,下面的写法是错误的,因为counter不是共享的,所以累加的功能是无法实现的)
val counter = new Counter();
val numbers = sc.parallelize(Array(1, 2, 3, 4, 5))
numbers.foreach(num => counter.add(num));

java和scala使用kryo序列化的用法:

如果要注册自定义的类型,那么就使用如下的代码,即可:

Scala版本:

val conf = new SparkConf().setMaster(...).setAppName(...)

conf.registerKryoClasses(Array(classOf[Counter] ))

val sc = new SparkContext(conf)

Java版本:

SparkConf conf = new SparkConf().setMaster(...).setAppName(...)

conf.registerKryoClasses(Counter.class)

JavaSparkContext sc = new JavaSparkContext(conf)

Kryo类库使用技巧:

1、优化缓存大小

如果注册的要序列化的自定义的类型,本身特别大,比如包含了超过100个field。那么就会导致要序列化的对象过大。此时就需要对Kryo本身进行优化。因为Kryo内部的缓存可能不够存放那么大的class对象。此时就需要调用SparkConf.set()方法,设置spark.kryoserializer.buffer.mb参数的值,将其调大。

默认情况下它的值是2,就是说最大能缓存2M的对象,然后进行序列化。可以在必要时将其调大。比如设置为10。

2、预先注册自定义类型

虽然不注册自定义类型,Kryo类库也能正常工作,但是那样的话,对于它要序列化的每个对象,都会保存一份它的全限定类名。此时反而会耗费大量内存。因此通常都建议预先注册号要序列化的自定义的类。

Kryo的使用场景:

首先,这里讨论的都是Spark的一些普通的场景,一些特殊的场景,比如RDD的持久化,

那么,这里针对的Kryo序列化类库的使用场景,就是算子函数使用到了外部的大数据的情况。比如说吧,我们在外部定义了一个封装了应用所有配置的对象,比如自定义了一个MyConfiguration对象,里面包含了100m的数据。然后,在算子函数里面,使用到了这个外部的大对象。

此时呢,如果默认情况下,让Spark用java序列化机制来序列化这种外部的大对象,那么就会导致,序列化速度缓慢,并且序列化以后的数据还是比较大,比较占用内存空间。

因此,在这种情况下,比较适合,切换到Kryo序列化类库,来对外部的大对象进行序列化操作。一是,序列化速度会变快;二是,会减少序列化后的数据占用的内存空间。

spark新能优化之序列化的更多相关文章

  1. spark新能优化之序列化的持久化级别

    除了对多次使用的RDD进行持久化操作之外,还可以进一步优化其性能.因为很有可能,RDD的数据是持久化到内存,或者磁盘中的.那么,此时,如果内存大小不是特别充足,完全可以使用序列化的持久化级别,比如ME ...

  2. spark新能优化之多次使用RDD的持久化或checkPoint

    如果程序中,对某一个RDD,基于它进行了多次transformation或者action操作.那么就非常有必要对其进行持久化操作,以避免对一个RDD反复进行计算. 此外,如果要保证在RDD的持久化数据 ...

  3. spark新能优化之shuffle新能调优

    shuffle调优参数 new SparkConf().set("spark.shuffle.consolidateFiles", "true") spark. ...

  4. spark新能优化之数据本地化

    数据本地化的背景: 数据本地化对于Spark Job性能有着巨大的影响.如果数据以及要计算它的代码是在一起的,那么性能当然会非常高.但是,如果数据和计算它的代码是分开的,那么其中之一必须到另外一方的机 ...

  5. spark新能优化之提高并行度

    实际上Spark集群的资源并不一定会被充分利用到,所以要尽量设置合理的并行度,来充分地利用集群的资源.才能充分提高Spark应用程序的性能. Spark会自动设置以文件作为输入源的RDD的并行度,依据 ...

  6. spark新能优化之广播共享数据

    如果你的算子函数中,使用到了特别大的数据,那么,这个时候,推荐将该数据进行广播.这样的话,就不至于将一个大数据拷贝到每一个task上去.而是给每个节点拷贝一份,然后节点上的task共享该数据. 这样的 ...

  7. spark新能优化之reduceBykey和groupBykey的使用

    val counts = pairs.reduceByKey(_ + _) val counts = pairs.groupByKey().map(wordCounts => (wordCoun ...

  8. Spark排错与优化

    一. 运维 1. Master挂掉,standby重启也失效 Master默认使用512M内存,当集群中运行的任务特别多时,就会挂掉,原因是master会读取每个task的event log日志去生成 ...

  9. [转] - Spark排错与优化

    Spark排错与优化 http://blog.csdn.net/lsshlsw/article/details/49155087 一. 运维 1. Master挂掉,standby重启也失效 Mast ...

随机推荐

  1. Rhel6-tomcat+nginx+memcached配置文档

    理论基础: User - > web ->nginx  ->tomcat1 ->*.jsp 80          8080 ↓      -> tomcat2 html ...

  2. 对项目的测试--Resharper

    初学 这里做个记录. 1:安装后,Resharper会用他自己的英文智能提示,替换掉 vs2010的智能提示,所以我们要换回到vs2010的智能提示 2:快捷键.是使用vs2010的快捷键还是使用 R ...

  3. Visual studio 2013安装及单元测试

    vs安装过程 单元测试: 创建c#类库 创建单元测试 测试结果

  4. T420修改wifi灯闪动模式

    给T420新装了centos7发现默认的配置wifi灯是工作时闪动的,有点晃眼,想改成简单的on 的时候常亮,off的时候常暗的模式 添加配置文件: vi /etc/modprobe.d/wlanle ...

  5. 安装eclipse for c/c++环境

    安装eclipse for c/c++环境:       1.启动eclipse,       2.选择Help->Install New Software...,在Work with的框框下复 ...

  6. javascript中创建对象的几种方式

    1. 使用Object构造函数来创建一个对象,下面代码创建了一个person对象,并用两种方式打印出了Name的值. var person = new Object(); person.name=&q ...

  7. linux学习笔记2:linux 下java开发的软件安装

    一.java ee开发环境的搭建 1.jdk的安装步骤 (1)首先必须要有安装文件,具体的可以去相关网站上下载,并制作iso文件 (2)将制作的iso文件挂载到linux系统上,并在虚拟机上将iso文 ...

  8. 捕获异常的两种方式Exception

    1.抛出异常:让调用此方法的代码去管 public static void GetFile() throws Exception{} package com.throwable; import jav ...

  9. poj1651 区间dp

    //Accepted 200 KB 0 ms //dp区间 //dp[i][j]=min(dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]) i<k<j #include ...

  10. iOS 实现简单的Http 服务

    http 是计算机之间通讯协议的比较简单的一种.在iPhone上,由于没有同步数据和文件共享,所以实现PC与设备之间的数据传输的最佳方式就是在程序中嵌套一个http 服务器.在这篇帖子中,我将简单的演 ...