“把接收缓冲变大可以延迟堵塞,但不会让一个永久不读数据的应用突然开始消费。流控把这种下游压力逐步传回发送端。这里滑动的是可接收序号范围;滑动窗口数据流则按时间或最近项数淘汰统计对象,二者不是同…”
形式陈述
两种窗口语义
滑动窗口流是数据流模型的窗口化特例:设流更新依次到达。计数窗口给定正整数
的最近
端点必须写清。把左端改为闭区间,会使恰在
过期不是一次反向更新
最直接实现是队列保存所有活跃项,到达时入队,越过边界时出队。计数窗口最多保存
append-only 摘要也不能直接复用。某元素过期时,算法未必还知道它是什么;而 distinct、分位数等摘要通常没有可逆的“减去最旧项”操作。有效结构要把历史压缩成带时间范围的桶或多个锚点摘要,使整段历史能够按边界批量淘汰。
直觉
窗口左边界不断推进,但小空间摘要通常已经忘记最旧的单项身份。可行方法把历史压成带时间范围的桶或后缀锚点:边界之外的整段直接丢弃,边界之内的整段完整保留,只让极少数跨界摘要承担可控误差。
图展示下述规则在
例子与边界
Exponential Histogram
以最近
桶按时间排列且互不交错,所以剩下的桶中至多只有最旧桶跨越窗口左边界。设其大小为
误差界来自桶数量的下界,而不只是“桶数不多”。一个大小为
从而
每级只有
例如
Smooth Histogram 框架
对满足平滑性条件的非负函数
及各后缀
查询选择夹住真实窗口起点的两个锚点,利用函数的平滑性把较长后缀的近似转成窗口近似。这里需要函数级定理,不能仅因摘要“可合并”就断言它支持删除任意前缀。
最近一小时 distinct count
网站以事件时间统计最近一小时独立用户。系统可在若干锚点维护 distinct sketch:10:00、10:20、10:35、10:47 等后缀摘要随新用户 ID 更新。当查询时刻从 11:00 推进到 11:08,真实窗口起点从 10:00 移到 10:08。起于 10:00 的后缀仍包含大量窗口内事件,因此不能因为起点过期就立即整份丢弃;10:00 与 10:20 两个后缀夹住真实起点,是否能据此给出所需近似,要由所选函数及摘要的窗口定理保证。
若使用 HyperLogLog 等摘要,合并寄存器可以组合不相交时间段,但不能从“截至现在”的寄存器中减去 10:00 前的用户。锚点框架负责过期语义,distinct sketch 负责每个后缀的集合基数估计;两者的误差和失败概率要共同配置。
同一用户在多个时间段重复出现不会给并集增加新元素。这也是不能用各桶 distinct 估计值直接相加的原因;必须合并能够处理重复的摘要状态,或采用为窗口 distinct 专门证明的结构。
乱序时间戳
若输入按事件时间有序,过期判断只需比较队首时间。真实系统常允许迟到
晚于容忍范围才到达的事件必须有明确策略:丢弃、修正历史结果,或触发重算。把处理时间窗口写成事件时间窗口,却没有 watermark 和迟到规则,会使同一输入因网络调度不同而产生不同含义。
推论与应用
边界与对照
滑动窗口不同于 turnstile 流。后者由输入显式给出正负更新,算法看到删除的是哪个键;窗口模型的删除由位置或时钟自动触发,键可能早已被压缩掉。它也不同于保存最后
窗口大小若小于一个桶、查询时间倒退、时间戳重复或窗口突然改长,都需要接口约定。经典算法通常假设窗口参数固定且查询时钟单调;动态扩大的窗口无法恢复已经丢弃的历史。
参考资料
- Mayur Datar, Aristides Gionis, Piotr Indyk and Rajeev Motwani, Maintaining Stream Statistics over Sliding Windows, SIAM Journal on Computing, 2002;作者稿 §2、§2.1、Theorem 1:最新时间戳、桶数量不变量与半桶误差。
- Vladimir Braverman and Rafail Ostrovsky, Smooth Histograms for Sliding Windows, FOCS, 2007.
- Graham Cormode, The Continuous Distributed Monitoring Model, SIGMOD Record, 2011.