在Spark应用开发中,很容易出现如下报错:

org.apache.spark.SparkException: Task not serializable
at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:304)
at org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:294)
at org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:122)
at org.apache.spark.SparkContext.clean(SparkContext.scala:2058)
...
Caused by: java.io.NotSerializableException

该报错意思是用户代码的transformation操作中包含不可序列化的对象引用。

本文主要从以下三个方面解释Spark 应用中序列化问题 。 
1、Java序列化含义? 
2、Spark代码为什么需要序列化? 
3、如何解决Spark序列化问题?

1、Java序列化含义?

Spark是基于JVM运行的进行,其序列化必然遵守Java的序列化规则。

序列化就是指将一个对象转化为二进制的byte流(注意,不是bit流),然后以文件的方式进行保存或通过网络传输,等待被反序列化读取出来。序列化常被用于数据存取和通信过程中。

对于java应用实现序列化一般方法:

  • class实现序列化操作是让class 实现Serializable接口,但实现该接口不保证该class一定可以序列化,因为序列化必须保证该class引用的所有属性可以序列化。

  • 这里需要明白,static和transient修饰的变量不会被序列化,这也是解决序列化问题的方法之一,让不能序列化的引用用static和transient来修饰。(static修饰的是类的状态,而不是对象状态,所以不存在序列化问题。transient修饰的变量,是不会被序列化到文件中,在被反序列化后,transient变量的值被设为初始值,如int是0,对象是null)

  • 此外还可以实现readObject()方法和writeObject()方法来自定义实现序列化。(具体用例见参考链接)

2、Spark的transformation操作为什么需要序列化?

Spark是分布式执行引擎,其核心抽象是弹性分布式数据集RDD,其代表了分布在不同节点的数据。Spark的计算是在executor上分布式执行的,故用户开发的关于RDD的map,flatMap,reduceByKey等transformation 操作(闭包)有如下执行过程: 
1. 代码中对象在driver本地序列化 
2. 对象序列化后传输到远程executor节点 
3. 远程executor节点反序列化对象 
4. 最终远程节点执行 
故对象在执行中需要序列化通过网络传输,则必须经过序列化过程。

3、如何解决Spark序列化问题?

如果出现NotSerializableException报错,可以在spark-default.xml文件中加入如下参数来开启SerializationDebugger功能类,从而可以在日志中打印出序列化出问题的类和属性信息。

spark.executor.extraJavaOptions  -Dsun.io.serialization.extendedDebugInfo=true
spark.driver.extraJavaOption -Dsun.io.serialization.extendedDebugInfo=true

对于scala语言开发,解决序列化问题主要如下几点:

  • 在Object中声明对象 (每个class对应有一个Object)
  • 如果在闭包中使用SparkContext或者SqlContext,建议使用SparkContext.get() and SQLContext.getActiveOrCreate()
  • 使用static或transient修饰不可序列化的属性从而避免序列化。 
    注:scala语言中,class的Object

对于java语言开发,对于不可序列化对象,如果本身不需要存储或传输,则可使用static或trarnsient修饰;如果需要存储传输,则实现writeObject()/readObject()使用自定义序列化方法。

此外注意

对于Spark Streaming作业,注意哪些操作在driver,哪些操作在executor。因为在driver端(foreachRDD)实例化的对象,很可能不能在foreach中运行,因为对象不能从driver序列化传递到executor端(有些对象有TCP链接,一定不可以序列化)。所以这里一般在foreachPartitions或foreach算子中来实例化对象,这样对象在executor端实例化,没有从driver传输到executor的过程。

dstream.foreachRDD { rdd =>
val where1 = "on the driver"
rdd.foreach { record =>
val where2 = "on different executors"
}
}
}

参考资料: 
Avoid NotSerializable Error in Spark Job 
spark not serializable problem 
Spark Streaming / Tips on Running Streaming Apps inside Databricks 
Java 序列化的高级认识 
什么是writeObject 和readObject?可定制的序列化过程

Spark 序列化问题的更多相关文章

  1. spark序列化及MapOutputTracker解析

    本文主要打算对spark内部的序列化机制以及在shuffle map中起衔接作用的MapOutputTracker做一下剖析.主要涉及具体实现原理以及宏观设计的一些思路. 1,spark序列化 任何一 ...

  2. spark系列-4、spark序列化方案、GC对spark性能的影响

    一.spark的序列化 1.1.官网解释 http://spark.apache.org/docs/2.1.1/tuning.html#data-serialization 序列化在任何分布式应用程序 ...

  3. 在Spark中使用Kryo序列化

    spark序列化  对于优化<网络性能>极为重要,将RDD以序列化格式来保存减少内存占用. spark.serializer=org.apache.spark.serializer.Jav ...

  4. 【Spark调优】Kryo序列化

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

  5. Spark性能优化(1)——序列化、内存、并行度、数据存储格式、Shuffle

    序列化 背景: 在以下过程中,需要对数据进行序列化: shuffling data时需要通过网络传输数据 RDD序列化到磁盘时 性能优化点: Spark默认的序列化类型是Java序列化.Java序列化 ...

  6. Hadoop的Writerable在Spark无法序列化的问题

    Spark序列化这块网上讲的比较少,自己还没来得及看这块代码,今天编程的时候遇到一个Hadoop的Writerable实现在Spark无法序列化的问题.我的代码如下: object EntryApp ...

  7. 浅谈Spark Kryo serialization

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3833985.html 最近在使用spark开发过程中发现当数据量很大时,如果cache数据将消耗很多的内 ...

  8. Spark调优与调试

    1.使用SparkConf配置Spark (1)在java中使用SparkConf创建一个应用: SparkConf conf =;i++){ javaBean bean =new javaBean( ...

  9. Spark生态以及原理

    spark 生态及运行原理 Spark 特点 运行速度快 => Spark拥有DAG执行引擎,支持在内存中对数据进行迭代计算.官方提供的数据表明,如果数据由磁盘读取,速度是Hadoop MapR ...

随机推荐

  1. POJ1039 Pipe

    嘟嘟嘟 大致题意:按顺序给出\(n\)个拐点表示一个管道,注意这些点是管道的上端点,下端点是对应的\((x_i, y_i - 1)\).从管道口射进一束光,问能达到最远的位置的横坐标.若穿过管道,输出 ...

  2. Webdriver API中文版

    Webdriver API中文版 1.1   下载selenium2.0的lib包 http://code.google.com/p/selenium/downloads/list 官方UserGui ...

  3. 解决error possibly undefined macro AC_MSG_ERROR

    问题 出现如下缺少宏的问题 error: possibly undefined macro: AC_MSG_ERROR error: possibly undefined macro: AC_SUBS ...

  4. FD.io社区中国行暨未来网络技术沙龙·南京站 会议小结

    What is FD.io VPP? FD.io VPP(Fast Data Input/Output Vector Packet Processing)is a new network multi- ...

  5. 离线服务器下docker的部署与应用

    一分钟内形成docker的模糊概念 网上很多文章避免将docker与虚拟机混为一谈,但对于初学者来说,完全可以将docker当做一种虚拟机技术,只需要牢牢记住一点最重要的区别:docker依赖于物理机 ...

  6. 【腾讯敏捷转型NO.1】敏捷是什么鬼?

    “敏捷是什么鬼” 最近对外进行<腾讯产品敏捷研发体系>授课的时候,我经常可以从参课学员的眼睛里找到这句话. 通常我会鼓励大家,说:“告诉大家一个好消息,你们今天所有的疑问都是有答案的,唯一 ...

  7. Java中的集合和常用类

    Java中的常用类: ▪ Object类 ▪ Math类 ▪ String类和StringBuffer类(字符串) ▪ 8种基本类型所对应的包装类 ▪ java.util包中的类——Date类 Obj ...

  8. File、Paths和Files类的使用详解

    Paths:通过get()方法返回一个Path对象,Path用于表示文件路径和文件. Files:提供了大量处理文件的方法,例如文件复制.读取.写入,获取文件属性.快捷遍历文件目录等..... Fil ...

  9. ionic3 返回多个页面的写法

    直接上代码 ionic3 返回2步  3步  或者多部 this.navCtrl.popTo(this.navCtrl.getByIndex(this.navCtrl.length()-3));   ...

  10. code#5 P2 棋子

    棋子   时间限制: 1.0 秒 空间限制: 512 MB 相关文件: 题目目录 题目描述 棋盘从左到右被分割成 n(n≤1000) 个格子,从左到右编号为1,2,...,n.棋盘上有 m(m≤n)  ...