资讯详情

Flink-数据流编程

数据流是一个可能无限的事件序列。

一.数据流图

数据流程序描述了数据如何在算子之间流动,节点表示算子, 表示数据之间的依赖。

算子是数据流图中的一个功能单元,用于接收输入的数据,并用于进一步处理。数据流图至少包含一个数据源和一个数据接收器。

二、数据并行与任务并行

首先,我们可以对输入的数据进行分区,并在数据子集执行具有相同算子的任务。这种并行性称为数据并行性。

第二,我们可以将不同算子在相同或不同的数据上执行。这种并行性称为任务并行性。

三、数据交换策略

数据交换策略定义了如何在物理执行流图中将数据分配给任务。

3.1 向前策略

将数据从一个任务发送到接收任务。如果两个任务位于同一个物理机器上,则可以避免网络通信。

3.2 广播通信

将所有数据发送到算子的所有并行任务上。由于该策略将复制数据并涉及网络通信,因此 相当贵。

3.3 键控的策略

通过Key数据分区保证相同Key同一任务将处理数据。在图2-2中,输出 “Extract hashtags”算子使用键来分区(hashtag),以便count算子的任务可以正确计算每个#标记 签名次数。

3.4 随机策略

将数据统一分配到算子任务中,使负载均匀分配到不同的计算任务中。

并行处理数据

数据流中的事件可以表示监控数据、传感器测量数据、信用卡交易数据、气象站观测数据、在线使用 户交互数据,网络搜索数据等。

四、延迟和吞吐量

流程处理程序与批处理程序不同。在评估性能时,要求也不同。我们通常关心批处理程序 操作的总执行时间,或我们的处理引擎读取输入所需的时间,执行计算,并重写结果。由于 流处理程序连续运行,输入可能无限,因此数据流处理中没有总执行时间的概念。 相反, 流程处理程序必须尽快提供输入数据的计算结果。我们用延迟和吞吐量来表示流处理的性能 要求。

延迟:

延迟表示处理事件所需的时间。这是接收事件和在输出中看到事件效果的时间 隔。

以时间为单位,如毫秒,在数据流中测量延迟。

吞吐量:

吞吐量是衡量系统处理能力的指标,即处理速率。

吞吐量以每个时间单位系统能处理的事件数量或操作数量来衡量。值得注意的是,事件处理 速度取决于事件到达的速度,低吞吐量并不一定意味着性能差。

延迟和吞吐量不是迟和吞吐量不是一个独立的指标。如果事件需要理流水线上停留很长时间,我们就不能轻易 确保高吞吐量。同样,如果系统容量很小,事件就会缓冲,必须等待才能处理。

五、数据流操作

流处理引擎通常提供一组内置操作:摄入(ingest),转换(transform)和输出流(output)。

5.1 数据的状态

无状态:

操作可以是无状态的或有状态的。无状态操作不保持任何内部状态。

事件的处理不依赖于过去看到的任何事件,也不保留历史。

无状态操作容易并行化,因为事件可以独立处理,也可以独立于事件到达的顺序(和事件) 到达顺序无关)。

无状态操作可以简单地重新启动,并从中断处继续处理。

有状态:

状态操作可以维护以前收到的事件的信息。

这种状态可以更新,也可以用于未来事件的逻辑处理。

状态流处理应用程序更难以平行和容错的方式运行,因为状态需要在故障发生时有效分区和可靠恢复。

5.2 数据的摄取

允许流程处理程序与外部系统通信数据摄入和数据出口操作。 数据摄取是从外部源获取原始数据并将其转换为其他格式的操作(ETL)。 实现数据提取逻辑的操作符称为数据源。数据源可以从TCP Socket,文件,Kafka Topic或传感 在数据接口中提取数据。 数据出口以适合消费的形式输出到外部系统。 数据出口的操作符称为数据接收器,包括文件、数据库、信息队列和监控接口。

5.3 数据的转换

转换算子是单次处理算子,遇到事件处理事件。

这些操作在使用后会消耗事件,然后对事件数据进行一些转换,产生新的输出流。

可以集成转换逻辑 操作符中或由UDF函数提供

5.4 数据的滚动聚合

例如,滚动聚合是一种聚合,sum,minimum和maximum,不断更新每个输入事件。

聚合操作处于状态,并与传入事件一起计算当前状态以产生更新的聚合值。

能够有效地将当前状态与事件结合起来产生单个值,聚合函数必须是相关的和可交换的。否则,操作 必须存储完整的流数据历史。 操作符保持当前最小值,并相应地更新每个输入事件的最小值。

六、窗口操作符

6.1 含义

转换和滚动聚合一次处理输出事件并可能更新状态。然而,必须收集和缓冲一些操作 计算结果的数据。

例如,考虑不同流之间的连接或整体聚合,如中值函数。为了在无界流上高效运行 我们需要限制一些操作符 这些操作维护数据量。

6.2 意义

如果我们只对最近的数据感兴趣呢?考虑应用程序,为司机提供实时交通信息。这个程序 它们可以避免拥挤的路线。在这种情况下,你想知道最近几分钟是否发生了事故。 另一方面,在这个应用场景下,了解所有发生的事故都没有鸡蛋用。更重要的是,通过将流历史 减少到单一聚合值,我们将在此期间丢失数据的变化。例如,我们可能想知道每5分钟有多少辆车 车辆穿过十字路口。

6.3 策略

窗口操作不断从无限事件流中创建有限事件集,使我们能够计算有限集。

事件通常根据数据属性或时间窗口进行分配。

为了正确定义窗口运算符语义,我们需要确定如何将事件分配给窗口,并对窗口中的元素进行频繁的值 什么样的率?

窗口的行为由一组策略定义。

窗口策略决定什么时候创建新窗口,什么时候分配事件,什么时候进入窗口元素 行求值。

一旦满足触发条件,窗口内容将发送到求值函数,求值函数将在窗口中应用计算逻辑 口中的元素。

可以是求值函数sum或minimal或自定义的聚合函数。 可根据时间或数据属性计算求值策略。

6.3.1 滚动窗口

滑动窗是将事件分配到固定大小的不重叠窗口。

当所有事件通过窗口结束时,将发送到求值函数进行处理。基于计数的滑动窗口定义了出发前需要收集多少事件。

每十分钟收集一次基于时间的窗口函数。

6.3.2 滑动窗口

滑动窗将事件分配到固定大小的重叠窗口。

滑动窗口定义为提供窗口长度和滑动距离。滑动距离定义了创建新窗口的间隔。

基于滑动计数的窗口有四个事件,三个是滑动距离。

6.3.3 会话窗口

会话窗在常见的真实场景中非常有用,有些场景既不能使用滚动窗也不能使用滑动窗。

考虑分析在线用户行为的应用程序。在应用程序中,我们想从同一时期的用户活动或对话 事件分组在一起。 会话由一系列相邻时间发生的事件组成,有一段时间没有活动。 例如,用户在App浏览一系列新闻,关掉App,那么浏览新闻这段时间的浏览事件就是 会话窗口没有事先定义窗口的长度,而是取决于数据的实际情况。滚动窗和滑动窗不能应用于 这个场景。相反,我们需要将同一会话中的事件分配到同一个窗口,而不同的会话可能会有很长的窗口 度不一样。 会话窗口将定义间隙值来区分不同的会话。间隙值是指用户认为用户在一段时间内不活动 会话结束了。 基于会话的窗口。

6.4 语义

窗口操作与时间语义和状态管理两个主要概念密切相关。 时间可能是流处理最重要的方面。即使低延迟是流处理的一个有吸引力的特真正价值也不仅仅是 快速分析。 在现实世界中,网络和通信渠道远不完善,流量数据往往被推迟或无序(无序)到达。 了解如何在这种情况下提供准确和确定的结果是非常重要的。 更重要的是,流处理程序可以遵循原样 处理事件的人也应该能够处理相同的历史事件,从而实现离线分析甚至时间旅行分析。 当 但前提是我们的系统可以保存状态,因为可能会出现故障。到目前为止,我们已经看到了所有的窗口类别 类型需要在生成结果之前保存以前的数据。事实上,如果我们想计算任何指标,即使是简单的计数, 我们还需要保存状态。考虑到流处理程序可能运行几天、几个月甚至几年,我们需要确保状态可能 在发生故障时可靠恢复。 即使程序崩溃,我们的系统也能确保计算出准确的结果。 本章将在流处理应用可能出现故障的背景下,深入探讨时间和状态的概念。

七、时间语义

7.1时间就是金钱

7.2 处理时间

处理时间是机器本地时钟(墙上时钟)的时间。 处理时间的窗口包含了一段时间内到达机器的所有事件。这段时间是指机器墙上的时钟。如 如下图所示,在Alice在这个例子中,处理时间窗口在Alice如果手机离线,时间会继续 走。但是这个处理时间窗口不会收集Alice手机离线时发生的事件。

7.3 事件时间

事件时间是流中事件实际发生的时间。事件时间是基于流中事件所包含的时间戳。 在事件进入流程处理程序之前,事件数据已包含时间戳。下图显示,事件时间窗口将正确 事件分发到窗口。事情是如实发生的。即使事件可能有延迟。 事件时间使计算结果过度不需要依赖处理数据的速度。基于事件时间的操作是可以预测的,而 计算结果也是确定的。无论流处理程序处理流数据的速度快或是慢,无论事件到达流处理程序的速 度快或是慢,事件时间窗口的计算结果都是一样的。 可以处理迟到的事件只是我们使用事件时间所克服的一个挑战而已。普遍存在的事件乱序问题可以 使用事件时间得到解决。考虑和Alice玩同样游戏的Bob,他恰好和Alice在同一趟地铁上。Alice和 Bob虽然玩的游戏一样,但他们的手机信号是不同的运营商提供的。当Alice的手机没信号时,Bob 的手机依然有信号,游戏数据可以正常发送出去。 如果使用事件时间,即使碰到了事件乱序到达的情况,我们也可以保证结果的正确性。还有,当我 们在处理可以重播的流数据时,由于时间戳的确定性,我们可以快进过去。也就是说,我们可以重 播一条流,然后分析历史数据,就好像流中的事件是实时发生一样。另外,我们可以快进历史数据来使我们的应用程序追上现在的事件,然后应用程序仍然是一个实时处理程序,而且业务逻辑不需 要改变。

 7.4 水位线

在我们对事件时间窗口的讨论中,我们忽略了一个很重要的方面:我们应该怎样去决定何时触发事 件时间窗口的计算?也就是说,在我们可以确定一个时间点之前的所有事件都已经到达之前,我们 需要等待多久?我们如何知道事件是迟到的? 在分布式系统无法准确预测行为的现实条件下,以及外部组件所引发的事件的延迟,以上问题并没 有准确的答案。在本小节中,我们将会看到如何使用水位线来设置事件时间窗口的行为。 水位线是全局进度的度量标准。系统可以确信在一个时间点之后,不会有早于这个时间点发生的事 件到来了。本质上,水位线提供了一个逻辑时钟,这个逻辑时钟告诉系统当前的事件时间。当一个 运算符接收到含有时间T的水位线时,这个运算符会认为早于时间T的发生的事件已经全部都到达 了。 对于事件时间窗口和乱序事件的处理,水位线非常重要。运算符一旦接收到水位线,运算符会认为 一段时间内发生的所有事件都已经观察到,可以触发针对这段时间内所有事件的计算了。 水位线提供了一种结果可信度和延时之间的妥协。 激进的水位线设置可以保证低延迟,但结果的准确性不够。在这种情况下,迟到的事件有可能 晚于水位线到达,我们需要编写一些代码来处理迟到事件。 如果水位线设置的过于宽松,计算的结果准确性会很高,但可能会增加流处理程序不必要的延 时。 在很多真实世界的场景里面,系统无法获得足够的知识来完美的确定水位线。在手游这个场景中, 我们无法得知一个用户离线时间会有多长,他们可能正在穿越一条隧道,可能正在乘飞机,可能永 远不会再玩儿了。水位线无论是用户自定义的或者是自动生成的,在一个分布式系统中追踪全局的 时间进度都不是很容易。所以仅仅依靠水位线可能并不是一个很好的主意。流处理系统还需要提供 一些机制来处理迟到的元素(在水位线之后到达的事件)。根据应用场景,我们可能需要把迟到事 件丢弃掉,或者写到日志里,或者使用迟到事件来更新之前已经计算好的结果。

7.5 写在最后

既然事件时间已经可以解决我们的所有问题,为什么我们还要对比这两个时间概念? 真相是,处理时间在很多情况下依然很有用。处理时间窗口将会带来理论上最低的延迟。 因为我们不需要考虑迟到事件以及乱序事件,所以一个窗口只需要简单的缓存窗口内的数据即可, 一旦机器时间超过指定的处理时间窗口的结束时间,就会触发窗口的计算。 对于一些处理速度比结果准确性更重要的流处理程序,处理时间就派上用场了。另一个应用场景 是,当我们需要在真实的时间场景下,周期性的报告结果时,同时不考虑结果的准确性。 一个实时监控的仪表盘,负责显示当事件到达时立即聚合的结果。最后,处理时间窗口可以提 供流本身数据的忠实表达,对于一些案例可能是很必要的特性。 例如我们可能对观察流和对每分钟事件的计数(检测可能存在的停电状况)很感兴趣。简单的 说,处理时间提供了低延迟,同时结果也取决于处理速度,并且也不能保证确定性。另一方 面,事件时间保证了结果的确定性,同时还可以使我们能够处理迟到的或者乱序的事件流。

八、Flink的四大基石

8.1 

Flink 基于 Chandy-Lamport 算法实现了一个分布式的一致性的快照,从而提供了一致性的语义。
Chandy-Lamport 算法实际上在 1985 年的时候已经被提出来,但并没有被很广泛的应用,而 Flink 则把这
个算法发扬光大了。
Spark 最近在实现 Continue streaming , Continue streaming 的目的是为了降低处理的延时,其也需要
提供这种一致性的语义,最终也采用了 Chandy-Lamport 这个算法,说明 Chandy-Lamport 算法在业界
得到了一定的肯定。
8.2 
提供了一致性的语义之后, Flink 为了让用户在编程时能够更轻松、更容易地去管理状态,还提供了一套
非常简单明了的 State API ,包括 ValueState 、 ListState 、 MapState , BroadcastState 。
8.3 
除此之外, Flink 还实现了 Watermark 的机制,能够支持基于事件的时间的处理,能够容忍迟到 / 乱序的数据。
8.4 
另外流计算中一般在对流数据进行操作之前都会先进行开窗,即基于一个什么样的窗口上做这个计算。
Flink 提供了开箱即用的各种窗口,比如滑动窗口、滚动窗口、会话窗口以及非常灵活的自定义的窗口。

标签: 常见传感器可监控司机

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台