Flink的数据类型和序列化

Apache Flink 以一种特有的方式来处理数据类型和序列化,包括自有的类型描述器、泛型抽取和类型序列化框架,本文将描述其背后的概念和原理。

Flink的类型处理

Flink试图去推断出在分布式计算过程中交换和存储的数据的类型信息,像数据库推断表模式一样。在大多数情况下,Flink可以自己无缝地推测出所有必要的信息。拥有类型信息Flink就可以完成如下的事情了:
  1、使用POJO类型,通过引用它们的字段名称对数据进行分组、连接和聚合操作,如dataSet.keyBy("username")。类型信息允许Flink可以提前对类型进行检测(如拼写错误和类型兼容性),而不是等到运行时再出错。
  2、Flink了解的数据类型信息越多,序列化和数据类型布局模式就更好,这在Flink的内存使用范例中是非常有用的。
3、最后,它还让用户在大多数情况下不再担心序列化框架和必须注册类型
通常,数据类型的信息都是在预处理阶段需要,即在程序对DataStream和DataSet的调用之前,及执行execute()、print()、count()和collect()的任何调用之前。

常见问题

用户与Flink的数据类型处理交互最常见的问题是:
  1、注册子类型:如果函数仅描述了超类型,但是执行过程中实际上使用的是这些超类的子类型,这样的话,Flink要识别这些子类型,可能会导致一定的性能下降。对此,可以在StreamExecutionEnvironment 或者 ExecutionEnvironment中调用 .registerType(clazz) 注册子类来解决。
  2、注册自定义序列化:对于不适用于自己的序列化框架的数据类型,Flink会使用Kryo来进行序列化,并不是所有的类型都与Kryo无缝连接。如,许多Google Guava集合类型,解决方案是为出问题的数据类型注册额外的序列化类,在StreamExecutionEnvironment 或者 ExecutionEnvironment 中调用.getConfig().addDefaultKryoSerializer(clazz, serializer)来实现,额外的Kryo序列化器在许多第三方库中都存在的,可以参考(自定义序列化器)[https://ci.apache.org/projects/flink/flink-docs-release-1.3/dev/custom_serializers.html]来了解更多如何创建自定义序列化器的信息。
  3、添加类型提示:有时,当Flink用尽各种手段都无法推测出泛型信息时,用户需要传入一个类型提示,这个只适用于JAVA API,类型提示部分描述了许多类型提示的信息。
  4、手动创建一个TypeInformation:对于某些API调用来说,这可能是必须的,因为Flink无法通过Java的通用类型擦除来推断数据类型。查看创建一个TypeInformation 或者 TypeSerializer来获取更多信息。

Flink的TypeInformation类

TypeInformation类是所有类型描述类的基类,它揭示了数据类型的一些基础属性,并产生序列化器在默写特殊情况下生成类型比较器(注意,Flink中的比较器不仅仅定义一个顺序,他们还是处理key的辅助工具utility)。
本质上,Flink通过类型来做出以下区分:
  基础类型:所有的Java原生类型及它们的封装类型,包括voidStringDateBigDecimalBigInteger
  原生数组和Object数组
  组合类型:
    Flink Java Tuples(Flink Java API的一部分):最多25个字段,空字段不支持
    Scala Case classes(包括Scala tuples):最多25个字段,空字段不支持
    Row:具有任意数量字段的元组,并支持空字段
    POJO:遵循某种Bean模式的类
  辅助类型:如:Option,Either,List,Maps,...
  泛型类型:这些不会被Flink自带的序列化器进行序列化,但是可以通过Kryo来进行
POJO非常有意思,因为它们支持创建复杂数据类型并通过字段名称来定义key:dataSet.join(another).where("name").equalTo("personName"),它们在运行时是透明的,并被Flink高效地处理。

POJO类型的规则

如果一个数据类型满足如下条件的话,就被认为是一个POJO类型:
  1、class是public的或者是独立的(不是非static内部类)
  2、class有无参构造函数
  3、所有class中的非静态的、非局部字段要么是public类型,要么有public类型的getter和setter方法

创建一个TypeInformation或者TypeSerializer

为一个数据类型创建一个TypeInformation,需要根据不同的语言来进行:

Java

因为Java通常会擦除类型信息,所以你需要将数据类型传递给TypeInformation构造函数:
对于非泛型数据类型,你可以传递Class:
TypeInformation<String> info = TypeInformation.of(String.class);
对于泛型数据类型,你需要通过TypeHint来捕获数据累心:
TypeInformation<Tuple2<String,String>> info = TypeInformation.of(new TypeHint<Tuple2<String,String>>(){});
在内部,这个创建了TypeHint的匿名子类,来捕获类型的泛型信息并保持知道运行时。

Scala

在Scala中,Flink使用编译时的宏,并在其任然可用时捕获所有通用类型信息

import org.apache.flink.streaming.api.scala._

val stringInfo: TypeInformation[String] = createTypeInformation[String]

val tupleInfo: TypeInformation[(String, Double)] = createTypeInformation[(String, Double)]

你也可以在Java中以回调函数的形式来使用同样的方法。

创建一个TypeSerializer,仅需要在TypeInformation类中调用typeInfo.createSerializer(config)即可。
config参数是ExecutionConfig类型的,并保持了程序注册的自定义serializer的信息,你可以通过DataStream或者DataSet的getExecutionCondif()方法来获取ExecutionConfig。在函数内部(如:MapFunction),你可以创建一个RichFunction并调用getRuntimeContext().getExecutionConfig()来获取它。

创建一个TypeSerializer,仅需要在TypeInformation类中调用typeInfo.createSerializer(config)即可。
config参数是ExecutionConfig类型的,并保持了程序注册的自定义serializer的信息,你可以通过DataStream或者DataSet的getExecutionCondif()方法来获取ExecutionConfig。在函数内部(如:MapFunction),你可以创建一个RichFunction并调用getRuntimeContext().getExecutionConfig()来获取它。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容