滑动窗口
连续视图会随时间持续不断地更新,因此PipelineDB能够结合当前时间来更新连续视图的结果。包含与当前时间相关的时间条件查询称为滑动窗口查询,WHERE子句过滤或接受的事件集会随着时间不断变化。
滑动窗口WHERE子句有两个重要组成部分:
clock_timestamp ( ):返回当前时间戳的内置函数。
arrival_timestamp:所有传入事件的一个特殊属性,即,PipelineDB接收它们的时间。
PipelineDB在内部执行此操作,仅需要在连续视图的定义中指定sw storage参数,没有必要显式添加引用这些值的WHERE子句。
快速示例
滑动窗口作为SQL数据库的新概念,PipelineDB不使用任何新的或特殊的窗口语法,而使用PostgreSQL 低版本就支持的语法。
统计前一分钟有哪些用户:
CREATE VIEW recent_users WITH (sw = '1 minute') AS
SELECT user_id::integer FROM stream;
在内部,PipelineDB将重写此查询为:
CREATE VIEW recent_users AS
SELECT user_id::integer FROM stream
WHERE (arrival_timestamp > clock_timestamp() - interval '1 minute');
在定义滑动窗口连续视图时,PipelineDB允许用户手动构造滑动窗口WHERE子句,不过为了便于理解,建议使用sw。
SELECT此连续视图的结果将仅包含在前一分钟内的用户。也就是说,即使未显式更新连续视图,重复执行SELECT也会包含不同的行。
每次计算clock_timestamp() - 1分钟时,返回对应于过去1分钟的时间戳。如果在给定事件中的arrival_timestamp大于该值,则为符合条件的事件。由于每次读取新事件时都会对此进行过滤,因此有效的提供了1分钟宽度的滑动窗口。
PipelineDB展示了要在查询中使用的current_date、current_time和current_timestamp值,但从实现上看,这些值不适用于滑动窗口查询,因为它们在事务中保持不变,因此不一定表示当前的时刻。
滑动聚合
滑动窗口查询还可以与聚合函数一起使用,滑动聚合通过尽可能多地聚合其输入,又不丢失随着时间的推移从窗口中删除信息所需的粒度。这种部分聚合过程对用户是完全透明的,在滑动窗口聚合中只有完全聚合的结果才可见。
统计前一分钟有多少用户:
CREATE VIEW count_recent_users WITH (sw = '1 minute') AS
SELECT COUNT(*) FROM stream;
每次SELECT此连续视图时,它返回的计数是前一分钟内的事件的计数。例如,如果事件停止进来,则每次在连续视图上运行SELECT时,计数都会减少,直至停止满一分钟。
统计传感器的5分钟平均温度:
CREATE VIEW sensor_temps WITH (sw = '5 minutes') AS
SELECT sensor::integer, AVG(temp::numeric) FROM sensor_stream
GROUP BY sensor;
统计前30天里有多少唯一用户:
CREATE VIEW uniques WITH (sw = '30 days') AS
SELECT COUNT(DISTINCT user::integer) FROM user_stream;
统计服务器在前5分钟内的99百分位响应延迟:
CREATE VIEW latency WITH (sw = '5 minutes') AS
SELECT server_id::integer, percentile_cont(0.99)
WITHIN GROUP (ORDER BY latency::numeric) FROM server_stream
GROUP BY server_id;
失效时间
连续视图中滑动窗口的数据行会在一定时间后失效,无法包含在连续视图的结果中。因此,必须对这些数据行进行垃圾收集,这可以通过两种方式进行:
后台进程:类似于PostgreSQL的autovacuumer的后台进程会定期运行,PipelineDB的后台清理进程会从滑动窗口连续视图中删除所有过期的行。
实时过滤:当使用SELECT读取连续视图时,任何太旧而无法包含在结果中的数据行都会在生成结果时被即时丢弃。这样可以确保即使无效数据行仍然存在,也不会误将它们包含在查询结果中。
步长因子
即使支持滑动窗口查询的数据表尽可能地进行聚合处理,也无法将数据行聚合到与查询的最终输出结果相同的粒度,因为超出窗口的数据,必须从聚合结果中删除。
例如,按小时聚合的滑动窗口查询实际上可能在磁盘上具有分钟级别的汇总数据,因此仅返回最后60分钟的结果。这些用于滑动窗口查询的内部更细粒度的聚合级别称为步骤,往往会在这些步骤聚合上放置一个汇总视图,用来在读取时执行最终聚合。
步骤聚合可能是确定滑动窗口查询读取性能的重要因素,因为每个最终的滑动窗口聚合内部都是由多个步骤组成的。PipelineDB为每个滑动窗口聚合组提供了步数调整参数step_factor。
step_factor:1到50之间的整数,指定滑动窗口步长的大小,以sw给出的窗口大小的百分比表示。 更小的step_factor将提供更细的粒度,以牺牲更大的磁盘上物化表的大小。更大的step_factor会减少磁盘上物化表的大小,但会减少窗口外的粒度。
举例,以30分钟粒度的步长聚合一个小时:
CREATE VIEW hourly (WITH sw = '1 hour', step_factor = 50)
AS SELECT COUNT(*) FROM stream;