在Flink应用程序中,我使用java.time.Instant表示UTC时间戳。该应用程序运行正常,但是我最近在Flink日志中注意到了此消息:
“类类java.time.Instant不能用作POJO类型,因为并非所有字段都是有效的POJO字段,必须将其作为GenericType处理。有关详细信息,请阅读\“ Data Types&Serialization \”上的Flink文档。对性能的影响。”
当我阅读文档时,关于使用Instant之类的性能降低的讨论很少。我的一般理解是,必须使用Kryo代替Flink的内置序列化器。我当前正在使用Flink 1.6,并且看到Flink 1.7及更高版本似乎具有InstantSerializer类。这是否意味着如果我升级Flink版本,那么使用Instant的POJO将不再需要作为GenericType处理?
通常,用来表示时间的最佳Java类是什么?是否可以使用Instant减轻或消除对性能的任何影响?
答案 0 :(得分:2)
日志消息有点误导,但您的理解是正确的。 Instant
在Flink 1.6中使用Kryo进行了序列化。
在Flink 1.7+中,Instant
将使用InstantSerializer
而不是KryoSerializer
进行序列化。
您的POJO是否会被视作,不取决于Instant
在POJO中的序列化方式。该消息只是表明系统试图查看Instant
是否为POJO。
示例:
public class SpecialMomentWithName {
private String name;
public Instant specialMoment;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SpecialMomentWithName
将始终在Flink中作为POJO处理。
在微基准测试中使用Kryo与新的InstanceSerializer序列化Instant
时,您可能会发现性能下降。
很难预测Flink作业的性能是否会从这种变化中受益:如果Instant
的序列化成本消耗了您的大部分CPU时间(并且您的工作受CPU限制),那么我希望性能得到改善。
如果您的网络或硬盘(使用RocksDB时)是限制因素,那么我预计性能不会得到改善。
如果不对您实际损失性能的位置进行分析,就不会优化Instance
序列化的性能。如果您发现自己的演奏受到这样的序列化时间的困扰,则可以尝试将实例表示为long
。这样会降低代码的可读性,并且潜在地需要额外的CPU周期来在类型之间进行转换。