以下讨论是在 apache Flink 的背景下:
想象我们有一个keyedStream
,其键是其id
,事件时间是时间戳,如果我们要计算每个事件的10分钟内到达多少事件。
需要解决的问题是:
- 如何设计窗口?
- 我们可以在每个事件到达后创建一个10分钟的窗口,但这意味着对于每个事件,由于等待10分钟的窗口,都会延迟10分钟。
- 我们可以创建一个10分钟的窗口,将每个事件的时间戳作为此窗口中的最大时间戳,这意味着我们不需要等待10分钟元素到达。但是,据我所知,这种窗口并不容易定义。
- 如何处理内存或其他资源问题?即使我们成功地创建了一个窗口,也许事件的ID是多种多样的,如此多的窗口,系统如何将其状态保持在内存中?记忆的可能性很大。
也许我在这里没有提到一些问题,或者除了窗口(即模式)外,还有一些好的解决方案。如果您有很好的解决方案,请给我一个线索,谢谢。
您可以使用全球风格和触发器进行此操作,而不是在每个事件上的火灾和驱逐者,该驱逐能够删除在计算其余事件之前超过10分钟的事件。(但是,天真的实施很容易表现很差。)
是的,这可能需要保持大量状态 - 您将在过去10分钟内保留每个事件(好吧,您只需要存储每个事件中的时间戳)即可。如果您设置了RockSDB状态后端,则Flink会在需要时溢出到磁盘,但要受到明显的惩罚。最好使用足够大的群集以保持10分钟的记忆。即使在每秒100万个事件中,每个事件都有32位时间戳,在10分钟内只有2.4GB(每秒100万个事件x 600秒x 4字节x 4个字节) - 似乎根本不是问题。