Event Time Versus Processing Time 事件时间vs.处理时间
要清晰地谈论无边界数据处理,需要对所涉及的时间域有一个清晰的理解。在任何数据处理系统中,通常有两个我们关心的时间域:
- 事件时间 Event time:事件实际发生的时间
- 处理时间 Processing Time:系统观察到事件的时间
大多数(并非全部)使用场景需要关注事件时间。比如随着时间的推移对用户行为进行定性,大多数计费应用,以及各种类型的异常检测。
理想的环境中,事件时间和处理时间总是一致的,事件一发生就被立即处理。然而,现实并非如此,事件时间和处理时间之间的偏差不仅不是零,而且往往是基于底层输入源、执行引擎和硬件等特性的可变函数。能够影响偏移水平的事情包括以下几点:
- 共享资源的限制,如网络拥堵、网络分区或非专用(nondedicated)环境下的共享CPU
- 软件原因,如分布式系统逻辑、纷争(contention)等
- 数据本身的特点,如密钥分发、吞吐量的差异或乱序。
因此,如果根据现实世界的系统中绘制事件时间对应处理时间的曲线,最终得到的东西通常看起来有点像图1-1中的红线。
图1-1. Time-domain mapping 时间域映射。x轴代表系统中的事件时间完整性;也就是说,到事件时间中的X时间为止,所有事件时间小于X的数据都被观察到。y轴代表处理时间的进度;也就是数据处理系统执行时观察到的正常时钟时间。
在图1-1中,斜率为1的黑色虚线代表理想状态,即处理时间和事件时间完全一致;红线代表实际情况。在这个例子中,系统在处理时间的开始阶段有点滞后,在中间阶段向理想状态靠拢,然后在最后阶段又有点滞后。乍一看,这张图中在不同的时间域有两种类型的倾斜:
- 处理时间 理论线和红线之间的垂直距离代表处理时间域的滞后。这个距离说明,给定时间的事件发生的时间和被处理的时间之间有多少延迟。
- 事件时间 理论线和红线之间的水平距离是那一刻处理管道中的事件时间偏移。表示管道目前比理想状态(在事件时间上)落后多少。
实际上,处理时间的滞后和事件时间的倾斜是同一件事。它们只是观察同一事物的两种方式。关于滞后/偏移的真正要点是:因为事件时间和处理时间之间的整体映射不是静态的(滞后/偏移可以随时间任意变化),分析数据的时候不能只分析观察到数据的时间,而忽略数据的事件时间(事件实际发生的时间)。然而之前的很多为无边界数据设计的系统就是这么运作的。为了应对无边界数据集的无限性,这些系统通常对传入数据进行窗口处理。我们稍后会深入讨论窗口化,但它本质上意味着将数据集沿着时间边界切成有限的片段。用处理时间来定义这些时间边界(即处理时间窗口化),再按照事件时间分析数据,这种操作无法满足正确性。因为处理时间和事件时间之间没有一致的相关性,一些事件时间数据最终会出现在错误的处理时间窗口中(出于分布式系统的固有滞后性,许多类型的输入源的在线/离线性质,等等),最终丢失正确性。
但是,即使对事件时间进行窗口化,情况也不完全乐观。在无边界数据的背景下,无序和变量偏斜造成了事件时间窗口完整性问题:在处理时间和事件时间之间缺乏一个可预测的映射,用户如何确定他已经观察到了给定事件时间X内的所有数据?对于许多现实世界的数据源,这是根本无法做到。但是今天使用的绝大多数数据处理系统都依赖于完整性的概念,这使得它们在迁移到无边界数据集时处于严重的劣势。
与其试图将无边界数据梳理成最终完整的有限批次的信息,不如设计一些工具来适应这些复杂的数据集所带来的不确定性。新的数据抵达的同时,旧的数据可能会被收回或更新,我们建立的任何系统都应该能够自行应对这些现实,完整性的概念是对特定和适当的用例的方便优化,而不是所有用例的语义必要性。