4. 时间语义(Time Semantics

这章我们会介绍时间语义,以及在流中,对于时间的各种不同的概念的描述。同时我们也会讨论一个流处理器在事件乱序的情况下,如何能提供精准的结果,以及如何使用流对历史events进行处理。

一分钟的含义

假设我们要持续的对流计算并生成结果,例如每一分钟。这里的“一分钟”在流处理应用里到底意味着什么呢?

考虑这么一个场景,一个程序用于分析手机网游用户的events。用户属于各个小队。基于小队成员达成游戏给定目标的速度,应用收集小队的信息并在游戏中给出奖励,例如升级、经验等。例如,如果一个小队的所有用户在一分钟内生产了500个泡泡,则他们获得一次升级。小明是其中一个玩家,他每天早上会在去上班的公交上玩这个游戏。可问题是,小明住在大山里,在出山的路上网络特别差。假设小明开始在游戏中生产泡泡,此时手机连接到了网络,并发送events到分析程序。突然,公交进入了一个隧道,导致他的手机断网了。小明继续玩游戏,此时events会缓存到他的手机里。当公交出了隧道,网络恢复后,pending的events会被发送到分析程序。此时分析程序怎么做?在这里一分钟意味着什么呢?是否考虑到了小明断网的时间?下图描述了此问题:

在线游戏是一个简单的场景,描述了 operator 语义如何依赖于时间。当events发生在某个时间段内,但是应用接收到events时已超过了这个时间段时,应用应如何处理时间语义?在这个手机游戏中,若是对此处理不当,会导致较差的客户体验。但是在一些非常看重时间的应用中,结果可能会更严重。如果仅考虑在一分钟内接收到多少个events,则结果会直接与于网络连接状况、或是处理速度等相关。所以,真正定义一分钟内的events时,应该与数据本身的时间相关。

例如在小明玩游戏这个例子中,流处理应用可以以两种时间概念进行操作:处理时间(processing time)或事件时间(event time)。接下来介绍这两种概念。

处理时间(Processing Time

处理时间是处理流的operator在执行时,所属机器上的本地时间。Processing-time 窗口包含所有在一个时间周期内到达window operator 的events,以本地机器时间衡量。如下图所示,在小明游戏的案例中,在小明的手机断开连接后,processing-time 窗口仍会持续计时,所以不会将小明断网时间内的events计入到当前时间段。

事件时间(Event Time

事件时间是一个event实际发生的时间,它基于事件流中event被打上的时间戳。时间戳一般存储与event 数据中。下图展示了一个event-time 窗口,可以正确的将events放入合适的窗口中,反应了事件实际发生的情况,即使事件的到达存在延迟。

事件时间将处理速度与结果完全解耦。基于事件时间的操作时可预测的(predictable)并且结果是明确的(deterministic)。使用事件时间窗口计算时,无论流处理的速度有多快,或是events到达operator的速度有多慢,它输出的一定是个相同的结果。

处理延迟的events仅仅是事件时间可以解决的众多问题中的一个。更普遍的数据乱序的问题,也可以由事件时间解决。假设小花是游戏的另一个玩家,她与小明都是做的同一班公交,在同一时间玩游戏,但是用的是不同的手机卡。在过隧道时,小明的手机没信号了,但是小花的手机还可以正常联网并向游戏应用继续发送events。

依赖于事件时间,我们可以在数据无序到达的情况下,依然保证事件的正确性。进一步的说,在结合了可重跑的流(replayable streams)时,明确的时间戳可以用于快速执行过去的数据(fast forward the past)。也就是说,你可以重跑(replay) 一个流并分析历史数据,就像events是实时发生的一样。同时,你也可以快进计算,直到到达当前的状态(fast forward the computation to the present),这样一旦应用获取了正在发生的事件时,它可以像一个实时应用一样,以同样的program logic继续工作。

水印(Watermarks

在讨论event-time 窗口时,我们忽略了一个很重要的方面:我们如何决定何时触发一个event-time 窗口?也就是说,我们需要等待多长时间,才能确保已经收到了在某个特定时间点之前发生的所有事件呢?并且我们如何知道数据会有延迟呢?很遗憾,这些问题是没有一个完美的答案的,因为分布式系统会有各种预料之外的异常,并且可能会有多方面的外部组件影响延迟。在这章我们会引入如何使用水印(watermarks)配置event-time窗口的行为。

水印是一个全局的进度指标(progress metric),表示的是:在什么时间点,我们可以有信心判断,之后不会有更多的(延迟的)事件到达。本质上,水印提供了一个逻辑时钟,提醒系统关于当前event time的信息。当一个operator收到了一个水印,时间为T。它可以假设:不会再有更多时间戳小于T的事件被收到。水印对于event-time窗口以及operators处理乱序events至关重要。一旦一个水印被接收到后,operators即被通知到:对于某个时间周期,所有的时间戳已经被观察到(observed),接下来应触发计算,或是将收到的事件进行排序。

水印提供了一个配置,用于权衡结果可信度与延迟。Eager watermarks可以确保低延迟,但是提供较低的可信度。在这种情况下,延迟的events可能会在水印之后到达,我们需要提供处理这些events的代码。另一方面,如果水印特别宽松,则我们对结果的准确度会有更大的信心,但是可能会增加不必要的处理延迟。

在很多真实应用中,系统并没有足够的知识去完美地准确算出水印。在手机游戏的例子中,基本是不可能预测用户会有多长的时间丢失连接。无论是自定义的水印或是自动生成的水印,在分布式系统中,由于有落后的tasks,跟踪整个分布式系统的进度可能仍是个问题。所以,如果仅简单的依赖于水印,则可能并不是一个很好的方法。更重要的是,流处理系统应提供一些机制去处理这些落后于水印的events。根据应用的需求,可以简单的丢弃这些事件,或是记录日志,亦或是使用它们去修正之前的结果。

处理时间vs事件时间

这里你可能会好奇既然event time可以解决我们所有的问题,那为什么还要提出processing time。事实上,处理时间在某些情况下是非常有用的。Processing-time 窗口可以尽可能地引入最低延时。例如:不考虑延迟及乱序事件,window仅是用于缓存一些数据,在到达一段时间后立即触发一个计算。所以对于那些速度比准确度更重要的应用来说,processing time 会更方便。另一个案例是定期实时提供报告结果,不考虑精准度。最后,processing-time窗口是流自身行为的一个体现,可能在某些场景下是一个很好的属性。例如,计算每秒收集到的事件,用于检测outage。总而言之,processing time 提供了低延时,但是输出的结果取决于处理的速度,并且结果并不是明确的。而event time保证了明确的结果,并可以处理延时或乱序的事件。

References

Vasiliki Kalavri, Fabian Hueske. Stream Processing With Apache Flink. 2019

Flink流处理(四)- 时间语义的更多相关文章

  1. Flink流处理的时间窗口

    Flink流处理的时间窗口 对于流处理系统来说,流入的消息是无限的,所以对于聚合或是连接等操作,流处理系统需要对流入的消息进行分段,然后基于每一段数据进行聚合或是连接等操作. 消息的分段即称为窗口,流 ...

  2. Apache Flink流式处理

    花了四小时,看完Flink的内容,基本了解了原理. 挖个坑,待总结后填一下. 2019-06-02 01:22:57等欧冠决赛中,填坑. 一.概述 storm最大的特点是快,它的实时性非常好(毫秒级延 ...

  3. Flink流处理(三)- 数据流操作

    3. 数据流操作 流处理引擎一般会提供一组内置的操作,用于对流做消费.转换,以及输出.接下来我们介绍一下最常见的流操作. 操作分为无状态的(stateless)与有状态的(stateful).无状态的 ...

  4. 带你玩转Flink流批一体分布式实时处理引擎

    摘要:Apache Flink是为分布式.高性能的流处理应用程序打造的开源流处理框架. 本文分享自华为云社区<[云驻共创]手把手教你玩转Flink流批一体分布式实时处理引擎>,作者: 萌兔 ...

  5. 02-flink时间语义 与 Window 基础概念与实现原理

    Flink 多种时间语义对比 Flink 在流应用程序中支持不同的 Time 概念,就比如有 Processing Time.Event Time 和 Ingestion Time.下面我们一起来看看 ...

  6. Flink流处理(一)- 状态流处理简介

    1. Flink 简介 Flink 是一个分布式流处理器,提供直观且易于使用的API,以供实现有状态的流处理应用.它能够以fault-tolerant的方式高效地运行在大规模系统中. 流处理技术在当今 ...

  7. FLINK流计算拓扑任务代码分析<一>

    我打算以 flink 官方的 例子 <<Monitoring the Wikipedia Edit Stream>> 作为示例,进行 flink 流计算任务 的源码解析说明. ...

  8. 解决Flink输出日志中时间比当前时间晚8个小时的问题

    Flink安装在CentOS7上,默认时间是UTC时间,查看Flink日志,发现输出时间比当前时间晚8个小时. 通过如下命令,调整成北京时间 cp /usr/share/zoneinfo/Asia/S ...

  9. FLINK流计算拓扑任务代码分析<二>

    首先 是 StreamExecutionEnvironment see = StreamExecutionEnvironment.getExecutionEnvironment(); 我们在编写 fl ...

随机推荐

  1. Django---Django安装数据库

    前面我们介绍了如何通过Django完成数据的接收和数据交互,那么我们都知道,数据一般都是通过数据库存储的,然而我们作为测试肯定和数据库也是经常打交道的,今天就简单的介绍下,如何在windows上安装数 ...

  2. CentOS虚拟机挂载U盘

    参考:https://www.cnblogs.com/jizhong/p/9410659.html 1.检查VMUSBArbService服务是否正在运行 2.在VMWare中连接插入的U盘 3.使用 ...

  3. x86 openwrt编译备忘录

    无需自己同步官方openwrt源码,采用Lean的openwrt源码是极好的,感谢Lean长久的坚持. https://github.com/coolsnowwolf/lede 准备工作 注意 不要用 ...

  4. poj1141题解

    题意 空序列是规则序列:用小括号(或者方括号)把一个规则序列括起来依然是规则序列:两个规则序列并列在一起仍然是规则序列. 给出一个括号字符串S,求一个规则序列ANS,满足S是ANS的子序列且ans尽可 ...

  5. LaTeX技巧007:每一章开始的header引用名言应该怎么做?

    [问题描述] 看到很多论文的每一章开始的右上角都有一段名人名言, 我试验了很多次一直都搞不清楚是怎么搞?是用fancyhead么?谁可以说说呢? 多谢了 [解决方案] 使用epigraph宏包来制作即 ...

  6. numpy学习(四)

    练习篇(Part 4) 41. How to sum a small array faster than np.sum? (★★☆) arr = np.arange(10) print(np.add. ...

  7. Could not connect to SMTP host: smtp.qq.com, port: 465, response: -1 SpringBoot发送邮件

    解决方案 换端口 QQ邮箱可以把端口换成587 设置属性 spring.mail.properties.mail.smtp.ssl.enable=true 原因 465端口是为SMTPS(SMTP-o ...

  8. JavaWeb学习(三) : 如何在 Eclipse 中创建一个Web 项目并成功运行?

    前置条件 : 1.确保已安装 Eclipse.Tomcat 服务器安装包 2.jdk.环境变量都已配置成功. 3.注意在安装 Eclipse 时一定要选择第二个有 Web 项目的进行安装, 不然安装成 ...

  9. Zookeeper学习笔记一

    目录 一.zookeeper介绍 二.Zookeeper安装 一.zookeeper介绍 1.概述   Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目.Hadoop ...

  10. AE接口编程

    [转]原文链接:https://malagis.com/arcgis-engine-10-develop-handbook-2-1.html 使用 ArcGIS Engine,也就意味着使用里面的接口 ...