深入理解流计算中的 Watermark( 二 )


然而如果游戏策划急于知道某个活动是否有带动玩家充值,希望看到每分钟更新的实时数据,那么上述题目改为用实时流计算去实现,此时要考虑的东西会复杂一点 。首先,我们可以依旧可以复用批处理的 what 和 where,即定义一个时间范围为 24 小时的窗口,计算逻辑和之前一样;在 when 方面,为了可以实时地得到最新的计算结果,我们需要定义每分钟输出一次最新的计算结果,直到达到 24 小时后输出最终结果;而在 how 方面,我们每次的输出结果只需要覆盖之前的结果即可 。然而 when 的问题并没有这么简单 。还记得我们之前说过数据采集延迟吗?可能一个用户充值的时间在 16:00,但中间采集的延迟可能有 1 min,导致到达服务器却是 16:01 分,如果基于充值记录被处理的时间(即 processing time)来进行窗口划分,用户充值记录可能会被计入错误的窗口,所以我们应该以用户充值这个时间(即 event time)发生的时间为准 。这里的难点在于我们计算时并不能判断所有 event time 窗口内的数据被收集完,因为数据的延迟是不可预知的,这被称为窗口完整性问题 。针对窗口完整性问题,The Dataflow Model 提出了 Watermark 的解决方案 。
Watermark 原理解析Watermark 并没有很正式的官方定义,最接近定义的是 Streaming 102 [3] 里的一段描述 。
A watermark is a notion of input completeness with respect to event times. A watermark with a value of time X makes the statement: “all input data with event times less than X have been observed.” As such, watermarks act as a metric of progress when observing an unbounded data source with no known end. 简单来说 Watermark 是一个时间戳,表示已经收集完毕的数据的最大 event time,换句话说 event time 小于 Watermark 的数据不应该再出现,基于这个前提我们才有可能将 event time 窗口视为完整并输出结果 。Watermark 设计的初衷是处理 event time 和 processing time 之间的延迟问题,三者的关系可以用下图展示:

深入理解流计算中的 Watermark

文章插图
 
理想的情况下数据没有延迟,因此 processing time 是等于 event time 的,理想的 Watermark 应该是斜率为 45 度的直线 。然而在真实环境下,processing time 和 event time 之间总有不确定的延迟,表现出来的 Watermark 会类似图 1 中的红色的曲线 。其中红色曲线与理想 Watermark 的纵坐标差值称为 processing-time lag,表示在真实世界中的数据延迟,而横坐标的差值表示 event-time skew,表示该延迟带来的 event-time 落后量 。
Watermark 通常是基于已经观察到的数据的 event time 来判断(当然也可以引入 processing time 或者其他外部参数),具体需要用户根据数据流的 event time 特征来决定,比如最简单的算法就是取目前为止观察到的最大 event time 。在数据流真实 event time 曲线是单调非减的情况下,比如 event time 是 Kafka producer timestamp 时,我们是可以计算出完美符合实际的 Watermark 的,然而绝大多数情况下数据流的 event time 都是乱序的,因此计算完美的 Watermark 是不现实的(实际上也是没有必要的),通常我们会以启发性的 Watermark 算法来代替 。
启发性的 Watermark 算法目的在于在计算结果的延迟和准确性之间找到平衡点 。如果采用激进的 Watermark 算法,那么 Watermark 会快于真实的 event time,导致在窗口数据还不完整的情况下过早输地出计算结果,影响数据的准确性;如果采用保守的 Watermark 算法,那么 Watermark 会落后于真实的 event time,导致窗口数据收集完整后不能及时输出计算结果,造成数据的延迟 。实际上上文所说的 Watermark 取观察到的最大 event time 和批处理使用的设置一个足够大的安全延迟的办法分别就属于 Watermark 算法的两个极端 。很多情况下用户偏向于牺牲一定的延时来换取准确性,不过在像金融行业的欺诈检测场景中,低延迟是首要的,否则准确性再高也没有意义 。针对这种情况 The Dataflow Model 提供了 allow lateness 的机制,工作的原理是用户可以设置一个时间阈值,如果在计算结果输出后的这个阈值时间内发现迟到的数据,计算结果会被重新计算和输出,但如果超出这个阈值的迟到数据就会被丢弃 。
这时你们可以看到要开发一个高质量的实时作业是多么不易了,这也是很多实时应用开发者最为头疼的地方,或许以后利用机器学习去计算 Watermark 是个不错的主意(然后我们的工作就可以愉快地从调 Watermark 算法参数变为调机器学习模型参数了 :) ) 。
Watermark 实践接下来我们将结合工业生产的案例来说明实战中 Watermark 是如何影响流计算的 。Watermark 在不同计算引擎的实现并不相同,本文将以笔者使用最多的 Apache Flink (下文简称 Flink)作为例子来说明 。


推荐阅读