转载自:https://mp.weixin.qq.com/s/EQgDUSf3TK0oVg1xmg-49Q

Checkpoint是Spark Streaming中的核心机制,它为应用程序的7*24小时LongRunning提供保证。Spark Checkpoint是基于JVM Serializable机制来实现,它会定时将整个Checkpoint对象从内存中序列化到外部存储(如HDFS),在应用程序异常重启时,对它进行反序列化,从而恢复到重启之前的状态。

但是基于JVM Serializable机制来实现Checkpoint存在一个缺陷:Checkpoint相关联的内部类或者业务类,在进行升级时,可能导致Checkpoint无法反序列化,进而导致升级失败。在Spark的Structured Streaming中,为规避该问题而采用Json来序列化相关数据https://databricks.com/blog/2017/01/19/real-time-streaming-etl-structured-streaming-apache-spark-2-1.html。

跟进 Structured Streaming来将传统的Streaming升级到使用Json序列化会是一件工作量很大的事情。因此我们从JVM Serializable机制本身出发来定位和解决这个问题。

1. JVM序列化机制

在JVM中,继承Serializable的类可以在运行时,通过ObjectOutputStream将对象从内存中以字节的形式序列化到流中,或者通过ObjectInputStream从流中反序列化出一个Object对象。

对于序列化,ObjectOutputStream会将对象的类名,SerialVersionUID,成员变量的描述信息,以及成员变量的值以一定的格式写到字节流中。如果成员变量为其他对象的引用,会递归的进行序列化。

对于反序列化,ObjectInputStream首先会读取字节流中类名,驱动JVM类加载器加载相应类到内存中,再从流中读取已序列化的SerialVersionUID,并与刚加载类的SerialVersionUID进行比较,如果它们相同,就继续后面的反序列化操作,否则会反序列失败,报InvalidClassException异常。

即使加载类与老的序列化类的Class字节码不同,只要SerialVersionUID相同,反序列化依然会成功的。如果新加载的类中添加了成员变量,将填充为默认值,被移除的成员变量将会被跳过。

2. 如何解决

反序列化成功或失败只受SerialVersionUID的值影响。对于Spark Streaming,只要我们对Checkpoint相关联的可序列化类都强制标记上SerialVersionUID,即可解决上述问题。

通过对Checkpoint类以及它的成员属性进行递归查找,确定Spark内部相关联的序列化类有:

通过使用JVM自带的serialver工具,获取未标记版本的类的SerialVersionUID。

serialver [-classpath classpath] [-show] [classname…]

并将这些SerialVersionUID手动的设置到相应类中,比如Checkpoint类: 

经过测试,该方案可行。

3. 后序

在Oracle官方API文档http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html,对SerialVersionUID是这样描述的:

However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization.

即为了提高SerialVersionUID的独立性和确定性,官方强烈建议在一个可序列化类中显示的定义SerialVersionUID,为它赋予明确的值。

对于Spark 社区来说,既然存在这样一个缺陷,为什么不跟进将每个可序列化类都强制标记上SerialVersionUID呢?在(SPARK-13084)https://issues.apache.org/jira/browse/SPARK-13084中有这样的讨论:

Serialversionuid is generally a bad idea. It opens up a worse problem: you claim compatibility when something isn’t because you forget to update the field. I don’t think it’s expected that a serialized RDD is compatible across any different versions. I would be against this in general

即社区并没有希望Spark版本之间是二进制兼容的,比如说:不希望Spark 1.4版本序列化的数据可以跑在Spark 1.5的版本上,也不希望Spark 1.4版本的Driver与Spark 1.5的Executor之间进行通信。

但是对于公司的平台来说,需要在Spark社区版本的基础上,进行升级来满足一些特定需求,此时小版本之间的序列化兼容成为一个必要的属性。

4. 延伸阅读

如果不显式设置,SerialVersionUID如何确定?在《Java Object Serialization Specification》http://docs.oracle.com/javase/7/docs/platform/serialization/spec/class.html#4100是这样描述的:

但是Spark是基于Scala开发的。除了上述相同的语法元素会影响SerialVersionUID以外,Scala自身一些语法元素也可能影响SerialVersionUID。

1. 修改类的访问权限(public,private)不影响SerialVersionUID。

2. 新增和删除val常量会影响SerialVersionUID。

3. 闭包会被编译为可序列化类,并且其SerialVersionUID永远为0,对闭包元素的修改都不影响SerialVersionUID。

4. case class会被编译为可序列化类,其SerialVersionUID影响因素与普通类相同。

5. 增加或删除伴身对象的字段或者方法,如果它与伴身类中成员同名,即不会影响伴身类的SerialVersionUID,否则会影响。

6. 伴身对象中定义的private字段或方法不会影响伴身类的SerialVersionUID。

Spark Streaming Checkpoint反序列化问题分析的更多相关文章

  1. Apache 流框架 Flink,Spark Streaming,Storm对比分析(一)

    本文由  网易云发布. 1.Flink架构及特性分析 Flink是个相当早的项目,开始于2008年,但只在最近才得到注意.Flink是原生的流处理系统,提供high level的API.Flink也提 ...

  2. Spark Streaming之四:Spark Streaming 与 Kafka 集成分析

    前言 Spark Streaming 诞生于2013年,成为Spark平台上流式处理的解决方案,同时也给大家提供除Storm 以外的另一个选择.这篇内容主要介绍Spark Streaming 数据接收 ...

  3. Apache 流框架 Flink,Spark Streaming,Storm对比分析(2)

    此文已由作者岳猛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 2.Spark Streaming架构及特性分析 2.1 基本架构 基于是spark core的spark s ...

  4. 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用

    https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...

  5. Apache 流框架 Flink,Spark Streaming,Storm对比分析(二)

    本文由  网易云发布. 本文内容接上一篇Apache 流框架 Flink,Spark Streaming,Storm对比分析(一) 2.Spark Streaming架构及特性分析 2.1 基本架构 ...

  6. Spark 实践——基于 Spark Streaming 的实时日志分析系统

    本文基于<Spark 最佳实践>第6章 Spark 流式计算. 我们知道网站用户访问流量是不间断的,基于网站的访问日志,即 Web log 分析是典型的流式实时计算应用场景.比如百度统计, ...

  7. spark streaming checkpoint

    Checkpoint机制 通过前期对Spark Streaming的理解,我们知道,Spark Streaming应用程序如果不手动停止,则将一直运行下去,在实际中应用程序一般是24小时*7天不间断运 ...

  8. Apache 流框架 Flink,Spark Streaming,Storm对比分析(1)

    此文已由作者岳猛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.Flink架构及特性分析 Flink是个相当早的项目,开始于2008年,但只在最近才得到注意.Flink是 ...

  9. Spark Streaming 与Filnk对比分析

    转:https://mp.weixin.qq.com/s/jllAegJMYh_by95FhHt0jA

随机推荐

  1. 巨头们的GitHub仓库整理

    1.Google >1.Google >https://github.com/google >2.Google Samples https://github.com/googlesa ...

  2. HDU1717--小数化分数2

    这道题是将输入的小数(有可能是无限循环小数)来化为分数.刚開始看到以为枚举(千万不要嘲笑我),可是感觉不正确. 所以百度了小数化为分数的方法,然后看到了各种方法,原来是这这样,在这我採用的是小数化为分 ...

  3. 怎么用ChemDraw加反应条件

    众所周知大部分化学反应都需要在一定的条件下才会发生,比较常见的条件有压力.通电.温度.光照等等.这些特定条件在化学上就叫反应条件.我们在使用ChemDraw这款化学绘图软件的时候,往往需要给我们的化学 ...

  4. oracle decode处理被除数为0 的情况

    ,,a) per from aa; 例如 我的b为(N30+N31+N32+N33+N34+N35+N36+N37+N38) ,,(N33)||'%' WHERE ssrq=''||sssq||'';

  5. 打开cmd闪退

    我们在使用电脑过程中一般会很少用到cmd命令,CMD命令窗口在一些特殊情况时我们会用到,如PING下看网络通不通.在CMD窗口里运行命令如磁盘格式转换,但是有些朋友遇到了这样的问题,在开始运行输入CM ...

  6. 用vue2.0实现点击选中active,其他选项互斥的效果

    在正常的js中.我们如果要实现点击选中active然后其他取消的效果,我们可以定义一个类,当点击的时候给给多有的dom取消active的类,给当前元素加上这个类名,说的很啰嗦,直接来看代码说话吧(表示 ...

  7. JMS和ActiveMQ的关系

    JMS和MQ的关系: JMS是一个用于提供消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程.而MQ则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的服务提供者 ...

  8. python的其他安全隐患

    零.绪论 python这里以python2.7为研究对象,对应的我们会简要说明一下python3,其他指与反序列化无关的安全隐患问题. 一.标准输入输出: 1.首先,我们来看下标准输入输出 impor ...

  9. Vue-cli 安装使用和理解

    Vue 的 官方文档 提到 点开这个链接,跟着文档一步步直到: $ npm install -g vue-cli $ vue init webpack my-project $ cd my-proje ...

  10. jenkins multijob 插件使用

    如果你想要停止对下游/上游工作链定义的混乱 当您想要添加具有层次结构的任务时,按顺序执行或并行执行 安装multijob插件可以让jenkins任务按照分组.顺序执行 jenkins版本:2.80 1 ...