Skip to main content

窗口关闭时触发(Emit On Window Close)

测试版功能

窗口关闭时触发目前处于测试阶段。如果您遇到任何问题或有任何反馈,请联系我们。

在流处理系统中,通常有两种类型的窗口计算触发策略:

  • 更新时触发(Emit On Update):此策略在窗口关闭之前计算并发送部分窗口结果。
  • 窗口关闭时触发(Emit On Window Close):此策略在窗口关闭时生成最终结果,并且此后将不再更改。

以下方查询为例:

SELECT window_start, COUNT(*)
FROM TUMBLE(events, event_time, INTERVAL '1' MINUTE)
GROUP BY window_start;
  • 更新时触发:采用此策略时,每当每个屏障通过时(默认间隔为 1 秒),聚合操作符就会向下游发送一个新的 count(*) 结果。这个更新后的计数随后会反映在物化视图里,或输出到外部系统中。
  • 窗口关闭时触发:当在 event_time 上定义的水位线超过时间窗口的结束时间时,聚合操作符会向下游发送最终的不可变聚合结果。这个结果代表了窗口的完整聚合,不会再发生变化。

RisingWave 默认采用的是更新时触发,以确保物化视图和基表之间的一致性。这一选择符合 SQL 视图的定义,并有助于保持系统的整体一致性。

然而,在某些情况下,为查询选择窗口关闭时触发的策略可能更合适。这些情况包括:

  • 当下游系统是仅追加的,如 Kafka 或 S3,我们更倾向于只在结果最终确定后写入结果,而不是进行多次写入和更新。
  • 当查询中的某些计算不能高效处理增量更新时,如百分位数计算,我们希望只在窗口关闭时触发计算,以获得更好的性能。

为了满足这些需求,RisingWave 提供了 EMIT ON WINDOW CLOSE 子句,用以将查询转换为窗口关闭时触发。此外,必须在数据源上定义水位线,因为它决定了窗口何时可以关闭。有关水位线的更详细解释,请参阅 水位线

我们可以修改上面的查询,以使用窗口关闭时触发:

CREATE MATERIALIZED VIEW window_count AS
SELECT window_start, COUNT(*)
FROM TUMBLE(events, event_time, INTERVAL '1' MINUTE)
GROUP BY window_start
EMIT ON WINDOW CLOSE;

请注意,需要为数据源事件定义水位线。

CREATE SOURCE t (
event_time TIMESTAMP,
<... 其他字段 ...>
WATERMARK FOR event_time AS event_time - INTERVAL '5 minutes'
) WITH ( ... );

进行此修改后,window_count 结果将不再包括来自最近窗口的任何部分聚合结果。相反,只有当 event_time 水位线超过窗口的结束时间时,才会交付最终结果。

哪些查询通过窗口关闭时触发能获得更好性能?

任何查询中,RisingWave 都支持使用窗口关闭时触发策略。但对于以下特定类型的查询,通过利用专门的操作符,RisingWave 能更大地提高性能。

按水位线列的顺序触发行的顺序

CREATE SINK s AS
select time, foo from t emit on window close;

窗口聚合

CREATE MATERIALIZED VIEW mv AS
SELECT
window_start, MAX(foo)
FROM TUMBLE(t, tm, INTERVAL '1 hour')
GROUP BY window_start
EMIT ON WINDOW CLOSE;

SQL 窗口函数

CREATE MATERIALIZED VIEW mv2 AS
SELECT
tm, foo, bar,
LEAD(foo, 1) OVER (PARTITION BY bar ORDER BY tm) AS l1,
LEAD(foo, 3) OVER (PARTITION BY bar ORDER BY tm) AS l2
FROM t
EMIT ON WINDOW CLOSE;