在阅读flink的文档并四处搜寻之后,我无法完全理解flink的窗口状态如何处理。 可以说我有一个每小时的滚动窗口,它具有一个聚合函数,可以将msg累积到某些Java pojo或scala case类中。 该窗口的大小将与在一小时内进入该窗口的事件的数量相关,或者仅将其与pojo / case类相关,因为会将事件累积到该对象中。 (例如,如果将10000 msgs计数为整数,大小将接近10000 * msg大小还是int大小?) 另外,如果即时通讯使用pojos或case类,flink是否为我处理状态(如果内存耗尽/在检查点保存状态等会溢出到磁盘)还是我必须使用flink的状态对象?
感谢您的帮助!
答案 0 :(得分:5)
窗口的状态大小取决于您应用的功能的类型。如果应用ReduceFunction
或AggregateFunction
,则将立即汇总到达的数据,并且窗口仅保留汇总的值。如果应用ProcessWindowFunction
或WindowFunction
,则Flink将收集所有输入记录,并在时间(事件或处理时间取决于窗口类型)超过窗口的结束时间时应用该函数。
您还可以结合使用两种类型的功能,即先后跟AggregateFunction
和ProcessWindowFunction
。在这种情况下,将立即汇总到达的记录,并且当关闭窗口时,汇总结果将作为单个值传递到ProcessWindowFunction
。这很有用,因为您具有增量聚合(由于ReduceFunction
/ AggregateFunction
),而且还可以访问窗口元数据,例如开始和结束时间戳记(由于ProcessWindowFunction
)。
如何管理状态取决于所选的状态后端。如果配置FsStateBackend
,则所有本地状态都将保留在TaskManager的堆上,并且如果状态过大,则会使用OutOfMemoryError
杀死JVM进程。如果您配置了RocksDBStateBackend
状态,则会泄漏到磁盘上。每次状态访问都伴随着反序列化费用,但为状态提供了更多的存储空间。