Flink序列化:POJO类型与GenericType

时间:2020-02-05 15:41:03

标签: apache-flink flink-streaming

在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减轻或消除对性能的任何影响?

1 个答案:

答案 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周期来在类型之间进行转换。