Flink 基于下面的规则来支持 POJO 类型状态数据结构的升级:
可以删除字段。一旦删除,被删除字段的前值将会在将来的 checkpoints 以及 savepoints 中删除。
可以添加字段。新字段会使用类型对应的默认值进行初始化,比如 Java 类型。
不可以修改字段的声明类型。
不可以改变 POJO 类型的类名,包括类的命名空间。
需要注意,只有从 1.8.0 及以上版本的 Flink 生产的 savepoint 进行恢复时,POJO 类型的状态才可以进行升级。 对 1.8.0 版本之前的 Flink 是没有办法进行 POJO 类型升级的。
如果Java和Scala类满足以下要求,Flink会将它们视为特殊的POJO数据类型:
类必须是公有的。
它必须有一个没有参数的公共构造函数(默认构造函数)。
所有字段要么是公共的,要么必须通过getter和setter函数访问。对于名为foo的字段,getter和setter方法必须命名为getFoo()和setFoo()。
已注册的序列化程序必须支持字段的类型。
pojo通常用PojoTypeInfo表示,并用PojoSerializer序列化(使用Kryo作为可配置的回退)。例外情况是pojo实际上是Avro类型(Avro特定记录)或产生为“Avro反射类型”。在这种情况下,POJO由AvroTypeInfo表示,并用AvroSerializer序列化。如果需要,你也可以注册你自己的定制序列化器;有关更多信息,请参阅序列化。
Flink分析POJO类型的结构,也就是说,它了解POJO的字段。因此,POJO类型比一般类型更容易使用。而且,与一般类型相比,Flink可以更有效地处理pojo。
下面的示例展示了一个带有两个公共字段的简单POJO。
public class TestStatData {
public String time;
public String initialUserNum;
public String preUserNum;
public TestStatData () {
}
public TestStatData (String time, String initialUserNum, String preUserNum) {
this.time= time;
this.initialUserNum= initialUserNum;
this.preUserNum= preUserNum;
}
}