我们将一些数据聚合1分钟,然后将其刷新到文件中。数据本身就像一个映射,其中键是一个对象,值也是一个对象。
由于我们需要一起刷新数据,因此我们不执行任何keyBy操作,因此使用windowAll。
我们面临的问题是,如果我们将窗口函数与ProcessAllWindowFunction一起使用,然后在进程调用中进行聚合,与将聚合与窗口函数一起使用相比,我们可以获得更好的吞吐量。当我们使用聚合时,我们还看到状态检查点超时。
我试着浏览了一下代码库,我能想到的唯一假设是,检查进程将使用的ListState与聚合将使用的AggregateState可能更容易。
这个假设正确吗?我们做错什么了吗?如果没有,是否有办法提高聚合性能?
根据你所说的,我将得出一些结论。
我假设您正在使用RocksDB状态后端,并将每个传入事件聚合到某种集合中。在这种情况下,RocksDB状态后端必须对该集合进行反序列化,将新事件添加到其中,然后对每个事件重新序列化。这很贵。
当您使用ProcessAllWindowFunction
时,每个传入事件都被附加到一个ListState
对象,这有一个非常有效的实现——新事件的序列化字节被简单地附加(列表不必反序列化和重新序列化(。
检查点超时是因为吞吐量太低。
切换到FsStateBackend
会有所帮助。或者使用ProcessAllWindowFunction
。或者使用KeyedProcessFunction
实现自己的窗口化,然后使用ListState
或MapState
进行聚合。