• sparkkryo 序列化

    2018-05-26 00:12:19
    几乎所有的资料都显示kryo 序列化方式优于java自带的序列化方式,而且在spark2.*版本中都是默认采用kryo 序列化。因此本文将做kryo 做一个测试以验证其性能。1.先给出定义: 把对象转换为字节序列的过程称为对象的...

    几乎所有的资料都显示kryo 序列化方式优于java自带的序列化方式,而且在spark2.*版本中都是默认采用kryo 序列化。因此本文将做kryo 做一个测试以验证其性能。

    1.先给出定义:
        把对象转换为字节序列的过程称为对象的序列化。
        把字节序列恢复为对象的过程称为对象的反序列化。

    通俗地说序列化就是把内存(jvm)中一个对象的状态通过网络传输,或者保存到磁盘上,反序列化与之相反。

    2.spark中的序列化
    那么对象以何种形式进行传输性能更好呢?
    在spark2.0+版本的官方文档中提到:spark默认提供了两个序列化库:Java自身的序列化和Kryo序列化
    官网的解释是:java序列化灵活,但是速度缓慢。Kryo序列化速度更快且更紧凑,但是支持的类型较少。

    而且spark现在已经默认RDD在shuffle的时候对简单类型使用了Kryo序列化。

    3.如何使用kryo 序列化
    spark中已经包含了kryo库,使用kryo只需要注册即可。官网只提供了scala版本的,java版本的如下:

    或者:System.setProperty("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
    两者都可以用,但是我测试好像没起到什么效果。于是需要手动注册:


    上图是关于kryo 的一些配置,可以单独注册自己的一个类,如紫色框线部分;
    也可以像红色框线部分一样,自定义一个接口实现类MyKryoRegistrator,在这个类里面将所需的类全部注册。具体操作如下图:
    如果需要序列化的类太多,就在这里逐一列举即可,当然被注册的类要实现java.io.Serializable,即:class TestKryo implements Serializable

    4.序列化的效果
    为了验证效果,我写了个test程序:


    5.测试结果:
    三种不同情况下的的RDD大小:
    默认不序列化:2017.0 KB
    在MyKryoRegistrator中序列化: 960.2 KB
    只序列化demo.TestKryo:1053.0 KB

    完。。。


    展开全文
  • Spark中,主要有三个地方涉及到了序列化: 在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输。 将自定义的类型作为RDD的泛型类型时(比如JavaRDD,Student是自定义类型),所有自定义类型对象,...

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

    • 在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输。
    • 将自定义的类型作为RDD的泛型类型时(比如JavaRDD,Student是自定义类型),所有自定义类型对象,都会进行序列化。因此这种情况下,也要求自定义的类必须实现Serializable接口。
    • 使用可序列化的持久化策略时(比如MEMORY_ONLY_SER),Spark会将RDD中的每个partition都序列化成一个大的字节数组。

    对于这三种出现序列化的地方,我们都可以通过使用Kryo序列化类库,来优化序列化和反序列化的性能。
    Spark默认使用的是Java的序列化机制,也就是ObjectOutputStream/ObjectInputStream API来进行序列化和反序列化。但是Spark同时支持使用Kryo序列化库,Kryo序列化类库的性能比Java序列化类库的性能要高很多。官方介绍,Kryo序列化机制比Java序列化机制,性能高10倍左右。Spark之所以默认没有使用Kryo作为序列化类库,是因为Kryo要求最好要注册所有需要进行序列化的自定义类型,因此对于开发者来说,这种方式比较麻烦。

    以下是使用Kryo的代码示例,我们只要设置序列化类,再注册要序列化的自定义类型即可(比如算子函数中使用到的外部变量类型、作为RDD泛型类型的自定义类型等):

    // 创建SparkConf对象。
    val conf = new SparkConf().setMaster(...).setAppName(...)
    // 设置序列化器为KryoSerializer。
    conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    // 注册要序列化的自定义类型。
    conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))
    

    转自原则八

    展开全文
  • 2.Spark序列化概述 在Spark的架构中,在网络中传递的或者缓存在内存、硬盘中的对象需要进行序列化操作,序列化的作用主要是利用时间换空间: 分发给Executor上的Task 需要缓存的RDD(前提是使用序列化方式缓存) ...

    1.美图

    在这里插入图片描述

    2.Spark序列化概述

    在Spark的架构中,在网络中传递的或者缓存在内存、硬盘中的对象需要进行序列化操作,序列化的作用主要是利用时间换空间:

    1. 分发给Executor上的Task
    2. 需要缓存的RDD(前提是使用序列化方式缓存)
    3. 广播变量
    4. Shuffle过程中的数据缓存
    5. 使用receiver方式接收的流数据缓存
    6. 算子函数中使用的外部变量

      上面的六种数据,通过Java序列化(默认的序列化方式)形成一个二进制字节数组,大大减少了数据在内存、硬盘中占用的空间,减少了网络数据传输的开销,并且可以精确的推测内存使用情况,降低GC频率。

    其好处很多,但是缺陷也很明显:

    ​ 把数据序列化为字节数组、把字节数组反序列化为对象的操作,是会消耗CPU、延长作业时间的,从而降低了Spark的性能。 至少默认的Java序列化方式在这方面是不尽如人意的。Java序列化很灵活但性能较差,同时序列化后占用的字节数也较多。

    ​ 所以官方也推荐尽量使用Kryo的序列化库(版本2)。官文介绍,Kryo序列化机制比Java序列化机制性能提高10倍左右,Spark之所以没有默认使用Kryo作为序列化类库,是因为它不支持所有对象的序列化,同时Kryo需要用户在使用前注册需要序列化的类型,不够方便。

    相关配置参数
    在这里插入图片描述

    配置说明:

    1. spark.serializer:序列化时用的类,需要申明为org.apache.spark.serializer.KryoSerializer。这个设置不仅控制各个worker节点之间的混洗数据序列化格式,同时还控制RDD存到磁盘上的序列化格式及广播变量的序列化格式。
    2. spark.kryoserializer.buffer:每个Executor中的每个core对应着一个序列化buffer。如果你的对象很大,可能需要增大该配置项。其值不能超过spark.kryoserializer.buffer.max
    3. spark.kryoserializer.buffer.max:允许使用序列化buffer的最大值
    4. spark.kryo.classesToRegister:向Kryo注册自定义的的类型,类名间用逗号分隔
    5. spark.kryo.referenceTracking:跟踪对同一个对象的引用情况,这对发现有循环引用或同一对象有多个副本的情况是很有用的。设置为false可以提高性能
    6. spark.kryo.registrationRequired:是否需要在Kryo登记注册?如果为true,则序列化一个未注册的类时会抛出异常
    7. spark.kryo.registrator:为Kryo设置这个类去注册你自定义的类。最后,如果你不注册需要序列化的自定义类型,Kryo也能工作,不过每一个对象实例的序列化结果都会包含一份完整的类名,这有点浪费空间
    8. spark.kryo.unsafe:如果想更加提升性能,可以使用Kryo unsafe方式

    3. Kryo使用

    conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");//设置序列化方式
    conf.registerKryoClasses(new Class[]{_KryoBean.class});//注册使用kryo序列化的类
    

    另外一种注册的方法

    //实现一个KryoRegistrator注册类,在该类里面对自定义的序列化类进行注册,然后在conf里面配置该类
    public class _KryoRegistor implements KryoRegistrator{
        @Override
        public void registerClasses(Kryo kryo) {
            kryo.register(_KryoBean.class, new FieldSerializer<>(kryo, _KryoBean.class));
            kryo.register(xxx.class, new FieldSerializer<>(kryo, xxx.class));
            ...
            ...
        }
    }
    
    //  在conf配置如下
    SparkSession spark = SparkSession.builder().appName("").master("local")
            .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
            .config("spark.kryo.registrator", _KryoRegistor.class.getName())
            .getOrCreate();
    
    展开全文
  • spark-kryo序列化方式

    2019-08-10 10:00:13
    Spark中,主要有三个地方涉及到了序列化: 在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输。 将自定义的类型作为RDD的泛型类型时(比如JavaRDD<SXT>,SXT是自定义类型),所有自定义类型...

                                          今天也要努力学习

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

    1. 在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输。
    2. 将自定义的类型作为RDD的泛型类型时(比如JavaRDD<SXT>,SXT是自定义类型),所有自定义类型对象,都会进行序列化。因此这种情况下,也要求自定义的类必须实现Serializable接口。
    3. 使用可序列化的持久化策略时(比如MEMORY_ONLY_SER),Spark会将RDD中的每个partition都序列化成一个大的字节数组。

    Kryo序列化器介绍:

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

    对于这三种出现序列化的地方,我们都可以通过使用Kryo序列化类库,来优化序列化和反序列化的性能。Spark默认使用的是Java的序列化机制,也就是ObjectOutputStream/ObjectInputStream API来进行序列化和反序列化。但是Spark同时支持使用Kryo序列化库,Kryo序列化类库的性能比Java序列化类库的性能要高很多。官方介绍,Kryo序列化机制比Java序列化机制,性能高10倍左右。Spark之所以默认没有使用Kryo作为序列化类库,是因为Kryo要求最好要注册所有需要进行序列化的自定义类型,因此对于开发者来说,这种方式比较麻烦。

    Spark中使用Kryo:

    1. SparkConf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    2. .registerKryoClasses(new Class[]{SpeedSortKey.class})

     

    总结以上代码优化,主要在编写代码时减少内存的使用,减少磁盘的IO。

    展开全文
  • 什么是Kryo序列化Kryo序列化是Saprk支持的一种序列化机制,用来序列化类。在Spark作业中,需要你手动设置。 Kryo序列化机制应用常场景: 1.持久化RDD时进行序列化(比如:内存持久化 + 序列化。 详见笔者文章...
    什么是Kryo序列化?

    Kryo序列化是Saprk支持的一种序列化机制,用来序列化类。在Spark作业中,需要你手动设置。

    Kryo序列化机制应用常场景:

    1.持久化RDD时进行序列化(比如:内存持久化 + 序列化。 详见笔者文章spark性能调优之RDD持久化) 每个executor分配了多个task,每个task对应有个partition,在将每个RDD partition序列化成一个大的字节数组的时候,就可以使用kyro进一步优化序列化的速率和性能。
    2.算子函数中使用到外部变量(详见笔者文章spark性能调优之Broadcast广播大变量)。
    3.Shuffle的时候也会用到Kryo序列化 。在进行stage之间的task的shuffle操作时,上一个stage生成的file文件,会通过网络传输拉取文件,此时,这些file文件既然要通过网络传输,也必然是要序列化的,尽可以使用kyro优化序列化。

     

    java序列化机制优缺点:

    默认情况,spark内部使用的是java序列化机制 – ObjectInStream/ObjectOutStream,对象输入/输出流机制来进行序列化。
    java序列化机制的好处:处理起来很方便,不需要人为做什么,只要你在算子里使用的变量实现serializable接口即可。
    java序列化机制的缺点:这种序列化的速度慢;序列化后的数据占用内存空间还是很大。

     

    Kryo序列化机制优缺点:

    Spark支持使用Kyro序列化机制。Kyro序列化机制比默认的java序列化机制,速度快;序列化后的数据更小,大概是java序列化后的1/10 。所以,Kyro序列化后,网络传输的数据也就变少,在集群中耗费的资源大大减少。但需要手动注册要Kryo序列化的类。

     

    如何设置Kryo序列化机制?

    第一步,在SparkConf中设置一个属性, sparkConf.set(“spark.serializer”,“org.apache.spark.serializer.KyroSerializer”)

    第二步,还是在SparkConf中,注册你使用到的且需要Kryo序列化的自定义类, sparkConf.registerKyroClasses(new Classes[]{Xxxx.class})

    展开全文
  • 使用Kryo优化序列化性能   在Spark中,主要有三个地方涉及到了序列化:   在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输(见“Spark优化(七):广播大变量”中的讲解)。 将自定义的...
  • SparkKryo序列化注册

    2017-01-13 10:37:25
    Spark序列化可以将RDD序列化来减少内存占用。 对于优化网络性能极为重要 spark.serializer=org.apache.spark.serializer.JavaSerializationSpark默认 使用Java自带的ObjectOutputStream 框架来序列化对象,这样任何...
  • 通常,内存足够的情况之下,网络带宽是瓶颈,这时我们就需要进行一些调优,比如用一种序列化的方式来存储RDD来减少内存使用,这边文章就讲两种方式,数据序列化和内存调优,接下来我们会分几个主题来谈论这个调优...
  • Kryo是Java生态中的一种序列化框架。许多软件组织在使用Dubbo(Dubbox)这套RPC框架时,经常会搭配使用 Kryo 作为其序列化方案。Kryo本身自带了很多针对 Java 原始数据类型 和 JDK常见类型的 序列化实现(如,...
  • 使用Kryo序列化的原因默认情况下,Spark内部是通过Java序列化(默认的序列化方式)形成一个二进制字节数组,大大减少了数据在内存、硬盘中占用的空间,减少了网络数据传输的开销,并且可以精确的推测内存使用情况,...
  • Kryo 是一个快速高效的Java对象图形序列化框架,主要特点是性能、高效和易用。该项目用来序列化对象到文件、数据库或者网络。代码地址:https://github.com/EsotericSoftware/kryo 样例代码地址:...
  • 文章目录修改默认序列化方式...因此 Spark 官方是推荐使用 Kryo 来代替默认的序列化方式的,为了便于调试,我们可以在 spark-shell 环境中更改默认的配置参数,使得默认的序列化方式变为 KryoSerializer。 $ ex...
  • 在 Apache Spark 中,对于大数据应用程序,建议使用 Kryo 序列化而不是 java 序列化。与 java 序列化相比,当您移动和缓存大量数据时,与 java 序列化相比,Kryo 占用的内存更少。 虽然 kryo 支持 RDD 缓存 和 ...
  • 使用Kryo优化序列化性能 Spark主要有三个地方涉及序列化: 1.算子函数中使用到外部变量时,该变量会被序列化后进行网络传输。 2.将自定义类型作为RDD的泛型类型时(比如Student是自定义类型),所有自定义类型对象...
  • 1.序列化Spark中的用处在算子函数中使用到外部变量时,该变量会被序列化后进行网络传输将自定义的类型作为RDD的泛型类型时(比如JavaRDD,Student是自定义类型),所有自定义类型对象,都会进行序列化。...
  • 前言:kryo是个高效的java序列化/反序列化库,目前Twitter、yahoo、Apache、strom等等在使用该技术,比如Apache的spark、hive等大数据领域用的较多。为什么使用kryo而不是其他?因为性能足够好。比kyro更高效的序列...
  • 参考文章: 1.Spark 配置Kryo序列化机制 https://www.jianshu.com/p/68970d1674fa 2.Spark kyro Serialization https://www.jianshu.com/p/141bb0244f64 3.Spark中使用kyro序列化 ...4.【Spark七十八】Spark Kyro...
  • Spark Application中,经常会使用到一个共享变量,众所周知的,Spark是一个并行计算框架,对于这个变量,每一个executor的task在访问它的时候,都会去拷贝一份副本去使用。如下图所示: 对于这种默认方式,它会...
  • 在SparkConf中设置一个属性,spark.serializer,org.apache...注册你使用到的,需要通过Kryo序列化的, 一些自定义类,SparkConf.registerKryoClasses() SparkConf.set("spark.serializer", "org.apache.spark.serial
  • set(“spark.serializer”,”org.apache.spark.serializer.KryoSerializer”)Java的序列化机制,ObjectOutputStream/ObjectInputStream 对象输入输入流机制,来进行序列化。这种默认序列化机制,的好处在于,处理...
1 2 3 4 5 ... 20
收藏数 2,666
精华内容 1,066