知识卡片
知道窗口何时"准备好":滞留事件与时钟校正
内容
用[[事件时间与处理时间的区别及其导致的错误]]中的事件时间来定义窗口有个棘手问题:你永远无法确定某个窗口的所有事件是否都已收齐——比如统计第37分钟的请求数,即便当前主要在处理第38、39分钟的事件,仍可能有属于第37分钟、正因网络中断而滞留在别处的事件正在路上。应对滞留事件通常有两条路:干脆忽略它们(把丢弃数量当监控指标,异常时报警),或者发布一个包含滞留事件的”更正”结果(可能还要收回之前已发出的输出);也可以让生产者发一个特殊消息表明”从现在起不会再有早于t的消息”来触发窗口关闭,但多生产者场景下每个生产者的阈值要分别跟踪,动态增删生产者会让这套机制变复杂。事件的时间戳本身还可能因缓冲位置不同而难以确定:一个离线使用的移动应用可能把事件本地缓存数小时甚至数天后才上报,此时用户交互发生的真实时间只能依赖设备本地时钟——但用户控制的设备时钟往往不可信(可能被无意或故意调错);服务器接收时间虽然更准确却不能反映用户实际交互的时刻。折中方案是记录三个时间戳(事件发生时间、设备发送时间、服务器接收时间,均分别取自设备时钟或服务器时钟),用服务器接收时间减设备发送时间估算两个时钟的偏移量,再把这个偏移应用回事件发生时间,从而校正出更接近真实的事件时刻——这不是流处理独有的问题,批处理同样存在,只是流处理场景下时间的流逝感更强,更容易意识到它。
参考来源
- 位置:《数据密集型应用系统设计》第十一章《流处理》"知道什么时候准备好了""你用的是谁的时钟?"(源文件:_epub-src/ch11_split_002.html)
- 结论依据:原文说明滞留事件的两种处理方式(忽略与发布更正)及特殊触发消息的局限,并给出记录设备/服务器三个时间戳来估算并校正设备时钟偏移的方法,直接支撑本卡片结论。
- 原始内容:忽略这些滞留事件……发布一个更正,一个包括滞留事件的更新窗口值……要校正不正确的设备时钟,一种方法是记录三个时间戳……通过从第三个时间戳中减去第二个时间戳,可以估算设备时钟和服务器时钟之间的偏移。