Flink13基础-数据类型

一、Flink 支持的数据类型

1. Flink 的类型系统

为什么会出现“不支持”的数据类型呢?因为 Flink 作为一个分布式处理框架,处理的是

以数据对象作为元素的流。如果用水流来类比,那么我们要处理的数据元素就是随着水流漂动

的物体。在这条流动的河里,可能漂浮着小木块,也可能行驶着内部错综复杂的大船。要分布

式地处理这些数据,就不可避免地要面对数据的网络传输、状态的落盘和故障恢复等问题,这

就需要对数据进行序列化和反序列化。小木块是容易序列化的;而大船想要序列化之后传输,

就需要将它拆解、清晰地知道其中每一个零件的类型,会有泛型擦除

为了方便地处理数据,Flink 有自己一整套类型系统。Flink 使用“类型信息”

(TypeInformation)来统一表示数据类型。TypeInformation 类是 Flink 中所有类型描述符的基类。

它涵盖了类型的一些基本属性,并为每个数据类型生成特定的序列化器、反序列化器和比较器。

2. Flink 支持的数据类型

简单来说,对于常见的 Java 和 Scala 数据类型,Flink 都是支持的。Flink 在内部,Flink

对支持不同的类型进行了划分,这些类型可以在 Types 工具类中找到:

(1)基本类型

所有 Java 基本类型及其包装类,再加上 Void、String、Date、BigDecimal 和 BigInteger。

(2)数组类型

包括基本类型数组(PRIMITIVE_ARRAY)和对象数组(OBJECT_ARRAY)

(3)复合数据类型

⚫ Java 元组类型(TUPLE):这是 Flink 内置的元组类型,是 Java API 的一部分。最多

25 个字段,也就是从 Tuple0~Tuple25,不支持空字段

⚫ Scala 样例类及 Scala 元组:不支持空字段

⚫ 行类型(ROW):可以认为是具有任意个字段的元组,并支持空字段

⚫ POJO:Flink 自定义的类似于 Java bean 模式的类

(4)辅助类型

Option、Either、List、Map 等

(5)泛型类型(GENERIC)

Flink 支持所有的 Java 类和 Scala 类。不过如果没有按照上面 POJO 类型的要求来定义,

就会被 Flink 当作泛型类来处理。Flink 会把泛型类型当作黑盒,无法获取它们内部的属性;它

们也不是由 Flink 本身序列化的,而是由 Kryo 序列化的。

在这些类型中,元组类型和 POJO 类型最为灵活,因为它们支持创建复杂类型。而相比之

下,POJO 还支持在键(key)的定义中直接使用字段名,这会让我们的代码可读性大大增加。

所以,在项目实践中,往往会将流处理程序中的元素类型定为 Flink 的 POJO 类型。

Flink 对 POJO 类型的要求如下:

⚫ 类是公共的(public)和独立的(standalone,也就是说没有非静态的内部类);

⚫ 类有一个公共的无参构造方法;

⚫ 类中的所有字段是 public 且非 final 的;或者有一个公共的 getter 和 setter 方法,这些

方法需要符合 Java bean 的命名规范。

所以我们看到,之前的 UserBehavior,就是我们创建的符合 Flink POJO 定义的数据类型。

3. 类型提示(Type Hints)

Flink 还具有一个类型提取系统,可以分析函数的输入和返回类型,自动获取类型信息,

从而获得对应的序列化器和反序列化器。但是,由于 Java 中泛型擦除的存在,在某些特殊情

况下(比如 Lambda 表达式中),自动提取的信息是不够精细的——只告诉 Flink 当前的元素由

“船头、船身、船尾”构成,根本无法重建出“大船”的模样;这时就需要显式地提供类型信

息,才能使应用程序正常工作或提高其性能。

为了解决这类问题,Java API 提供了专门的“类型提示”(type hints)。

回忆一下之前的 word count 流处理程序,我们在将 String 类型的每个词转换成(word,

count)二元组后,就明确地用 returns 指定了返回的类型。因为对于 map 里传入的 Lambda 表

达式,系统只能推断出返回的是 Tuple2 类型,而无法得到 Tuple2<String, Long>。只有显式地

告诉系统当前的返回类型,才能正确地解析出完整数据。

.map(word -> Tuple2.of(word, 1L))
.returns(Types.TUPLE(Types.STRING, Types.LONG));

这是一种比较简单的场景,二元组的两个元素都是基本数据类型。那如果元组中的一个元

素又有泛型,该怎么处理呢?

Flink 专门提供了 TypeHint 类,它可以捕获泛型的类型信息,并且一直记录下来,为运行

时提供足够的信息。我们同样可以通过.returns()方法,明确地指定转换之后的 DataStream 里元

素的类型。

returns(new TypeHint<Tuple2<Integer, SomeType>>(){})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值