Apache Flink: 状态何时进行序列化/反序列化?

8

Flink在何时进行操作状态的序列化/反序列化?是在每次get/update时还是基于检查点?状态后端是否有影响?

我怀疑,在具有多样化键(数百万)和每个键每秒数千个事件的键控流情况下,序列化/反序列化可能是一个大问题。我对吗?

1个回答

9
您的假设是正确的。这取决于状态后端。
在JVM堆上存储状态的后端(MemoryStateBackend和FSStateBackend)在常规读/写访问时不对状态进行序列化,而是将其保留为堆上的对象。虽然这可以实现非常快速的访问,但您显然受制于JVM堆的大小,并可能面临垃圾回收问题。当执行检查点时,对象会被序列化并持久化以便在发生故障时进行恢复。
相比之下,RocksDBStateBackend将所有状态作为字节数组存储在嵌入式RocksDB实例中。因此,它会对每个读/写访问键的状态进行序列化/反序列化。您可以通过选择适当的状态原语(ValueState、ListState、MapState等)来控制“有多少”状态被序列化。
例如,ValueState总是作为整体进行序列化/反序列化,而MapState.get(key)仅对键进行序列化(用于查找),并对返回的键值进行反序列化。因此,您应该使用MapState而不是ValueState>。其他状态原语也需要类似的考虑。
RocksDBStateBackend通过将文件复制到持久性文件系统来对其状态进行检查点。因此,当执行检查点时,不涉及任何额外的序列化。

我认为MemoryStateBackend和使用de/serialization创建副本有一点小问题。https://www.youtube.com/watch?v=dWQ24wERItM解释了这个问题,但我忘记了细节... - Caesar
1
有没有一种方法可以配置Flink(使用RocksDBStateBackend),使其将最近访问的状态保留在内存中,并保存大量的序列化/反序列化? 序列化可以仅针对检查点或在LRU驱逐时进行。 序列化/反序列化会影响我的应用程序性能,占用了processFunction处理过程中90%的时间。 - user368507
很抱歉,目前不支持RocksDB状态后端的缓存功能。 - Fabian Hueske
我看了Caesar提到的视频,这里是他们谈论它的地方。https://youtu.be/dWQ24wERItM?t=1148。在检查点之后从堆状态获取数据时,它将创建一个副本,同时仍然异步复制数据到状态文件。这可以防止程序在对象仍在保存时修改它。 - Ben L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接