Apache Flink:状态 de/serialized 多久出现一次?
Apache Flink: How often is state de/serialized?
Flink de/serialise operator 状态的频率如何?根据 get/update 还是基于检查点?状态后端有什么不同吗?
我怀疑在密钥流具有不同密钥(数百万)并且每个密钥每秒有数千个事件的情况下,de/serialization 可能是一个大问题。我说得对吗?
你的假设是正确的。这取决于状态后端。
在 JVM 堆上存储状态的后端(MemoryStateBackend
和 FSStateBackend
)不会为常规 read/write 访问序列化状态,而是将其作为对象保存在堆上。虽然这会导致非常快的访问,但您显然受限于 JVM 堆的大小,并且还可能面临垃圾收集问题。采取检查点时,对象将被序列化并持久化以在发生故障时启用恢复。
相比之下,RocksDBStateBackend
将所有状态存储为嵌入式 RocksDB 实例中的字节数组。因此,它 de/serializes 每次 read/write 访问的密钥状态。您可以通过选择适当的状态原语来控制 "how much" 状态序列化,即 ValueState
、ListState
、MapState
等。
例如,ValueState
作为一个整体总是de/serialized,而MapState.get(key)
只序列化键(用于查找)并反序列化键的返回值。因此,您应该使用 MapState<String, String>
而不是 ValueState<HashMap<String, String>>
。类似的考虑适用于其他状态原语。
RocksDBStateBackend
通过将文件复制到持久文件系统来检查其状态。因此,在采取检查点时不涉及额外的序列化。
Flink de/serialise operator 状态的频率如何?根据 get/update 还是基于检查点?状态后端有什么不同吗?
我怀疑在密钥流具有不同密钥(数百万)并且每个密钥每秒有数千个事件的情况下,de/serialization 可能是一个大问题。我说得对吗?
你的假设是正确的。这取决于状态后端。
在 JVM 堆上存储状态的后端(MemoryStateBackend
和 FSStateBackend
)不会为常规 read/write 访问序列化状态,而是将其作为对象保存在堆上。虽然这会导致非常快的访问,但您显然受限于 JVM 堆的大小,并且还可能面临垃圾收集问题。采取检查点时,对象将被序列化并持久化以在发生故障时启用恢复。
相比之下,RocksDBStateBackend
将所有状态存储为嵌入式 RocksDB 实例中的字节数组。因此,它 de/serializes 每次 read/write 访问的密钥状态。您可以通过选择适当的状态原语来控制 "how much" 状态序列化,即 ValueState
、ListState
、MapState
等。
例如,ValueState
作为一个整体总是de/serialized,而MapState.get(key)
只序列化键(用于查找)并反序列化键的返回值。因此,您应该使用 MapState<String, String>
而不是 ValueState<HashMap<String, String>>
。类似的考虑适用于其他状态原语。
RocksDBStateBackend
通过将文件复制到持久文件系统来检查其状态。因此,在采取检查点时不涉及额外的序列化。