Flink中的序列化失败问题 和transent声明

最近在Flink的的map算子中使用了自义定类(实现richMapFunction)来序列化中存在的问题?

一、背景介绍

在编写Spark程序中,由于在map等算子内部使用了外部定义的变量和函数,从而引发Task未序列化问题。然而,Spark算子在计算过程中使用外部变量在许多情形下确实在所难免,比如在filter算子根据外部指定的条件进行过滤,map根据相应的配置进行变换等。为了解决上述Task未序列化问题,这里对其进行了研究和总结。
(其实在Flink中也存在该问题)

二、原因分析

链接:http://www.sjsjw.com/103/005844MYM031811/
其实看看这个原因就差不多了

三、解决方案

3.1.先说一下网上已有的解决办法:

(这是对Spark而言的,其实对Flink也是适用的,没试过)
  承上所述,这个问题主要是引用了某类的成员变量或函数,并且相应的类没有做好序列化处理导致的。因此解决这个问题无非以下两种方法:
不在(或不直接在)map等闭包内部直接引用某类(通常是当前类)的成员函数或成员变量
如果引用了某类的成员函数或变量,则需对相应的类做好序列化处理

(一)不在(或不直接在)map等闭包内部直接引用某类成员函数或成员变量

  • (1)对于依赖某类成员变量的情形
    如果程序依赖的值相对固定,可取固定的值,或定义在map、filter等操作内部,或定义在scala
    object对象中(类似于Java中的static变量)
    如果依赖值需要程序调用时动态指定(以函数参数形式),则在map、filter等操作时,可不直接引用该成员变量,而是在类似上面例子的getResult函数中根据成员变量的值重新定义一个局部变量,这样map等算子就无需引用类的成员变量。

  • (2)对于依赖某类成员函数的情形
    如果函数功能独立,可定义在scala object对象中(类似于Java中的static方法),这样就无需一来特定的类。

(二)如果引用了某类的成员函数或变量,则需对相应的类做好序列化处理

对于这种情况,则需对该类做好序列化处理,首先该类继承序列化类,然后对于不能序列化的成员变量使用“@transent”标注,告诉编译器不需要序列化。
此外如果可以,可将依赖的变量独立放到一个小的class中,让这个class支持序列化,这样做可以减少网络传输量,提高效率。

3.2我的解决方法:

【首先声明:我的程序是Scala+Java混合方式实现的Flink程序(Storm迁移至Flink)】

方法1:声明为@transent

在map()算子中继承了的RichMapFunction的类,其中的由于对象都需要序列化,但是对于不能够实现的序列化接口的对象比如数据库连接对象SqlConnection(mySQL、Postgresql等)和GeomentyFactory对象等,自身不可以序列化的对象,则声明为@transent
再分为两点
(1)对象在需要在map()中不停调用的时候,这时候需要在open()中序列化,这个跟设置的并发线程数有关系。比如设置并发parallel=10,则该对象被初始化10次,生成是个对象,分别被10个线程调用;
(2)假如对象只需要在在后期实用一次,比如数据库连接SqlConnection在加载一次缓存(一般是不变的缓存),则最好是放在该类的构造函数中初始化,执行1次;

方法2:声明为静态

对于像数据库连接对象SqlConnection等不可以序列化的对象,由于该对象是长连接不可变对象,可以声明为静态对象(类对象),JVM会将该对象放入永久代Perminate 中,实现Flink多线程共享并发访问;
同理,所有不可变的小对象(不可变缓存(如hashMap)是指小的缓存对象)都可以声明为静态对象,因此,此时不用对该对象声明为@transent而表明不可以序列化;

(推荐使用 :方法2:声明为静态对象,简单易用!)


自身在Flink使用中遇到的问题,后续会继续跟踪该类问题,并更新博客!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值