在本文中,我们将致力于让您更好地了解使用 Flink 自下而上的流处理;云服务和其他平台提供流处理解决方案(对于某些平台,Flink 集成在引擎盖下)。如果您错过了基础知识,本指南是为您介绍的。
我们的单体解决方案无法应对传入数据增加的负载,因此必须不断发展。现在是我们下一代产品的时候了。与迄今为止实现的批处理相比,流处理是新的数据引入范例。
因此,我的团队开始使用 Flink 处理信息。有很多关于Flink的功能和好处的文章。Cloudera 分享了一张关于 Flink 的优秀幻灯片;本文是一个实用的实践指南,了解如何从基础知识构建一个简单的流处理应用程序。
阿帕奇Flink在短
Apache Flink 是一个可扩展的分布式流处理框架,这意味着它能够处理连续的数据流。此框架提供多种功能:源、流转换、并行处理、调度、资源分配和广泛的目标。它的一些连接器是HDFS,卡夫卡,亚马逊基尼塞,兔子MQ和卡桑德拉。
Flink 以其高吞吐量和低延迟而闻名,支持一致性(所有数据一次处理,无需重复),并且还支持高可用性。与任何其他成功的开源产品一样,它具有广泛的社区来培养和扩展其功能。
Flink 可以处理不确定的数据流或明确的数据集。此博客将侧重于前者(使用 DataStream
对象)。
流处理 :挑战
如今,当物联网设备和其他传感器无处不在时,数据会源源不断地流动。这种无休止的数据流迫使传统的批处理计算适应。
- 此数据是无界的;没有开始和结束。
- 新数据的不可预测和不一致的时间间隔
由于这些独特的特点,处理和查询数据是复杂的任务。结果变化迅速,几乎不可能得出明确的结论;有时,当尝试生成有效结果时,计算可能会受到阻碍。此外,结果不可重复,因为数据不断变化。最后,延迟是一个因素,因为它会影响结果的准确性。
Apache Flink 基于传入数据源中的时间戳进行处理,从而解决这些问题。在应用处理执行之前,它有一种机制来根据事件的时间戳来累积事件。它消除了微批次的使用,并因此提高了结果的准确性。
Flink 完全实现一次一致性,这可确保计算的正确性,而无需开发人员编程。
基础 : 链接包构建基块
Flink 主要从各种来源引入流。基本对象是 DataStream<T>
,它表示相同类型的元素流;其元素的类型是通过设置泛型类型 T(在此处阅读有关DataStream 对象)在编译时定义的。
DataStream 对象包含许多用于转换、拆分和筛选其数据的有用方法[1]。熟悉方法映射、减少和筛选是一个良好的开端;这些是主要的转换方法:
映射:接收 T 对象并返回 R 类型对象的结果;Map函数在 DataStream 对象的每个元素上仅应用一次。
单输出流操作员地图(T减少:接收两个连续值,并在将它们合并到同一对象类型后返回一个对象;此方法在组中的所有值上运行,直到仅保留一个值。
T reduce(T value1, T value2)
筛选器: 接收 T 对象并返回 T 对象的流;此方法在 DataStream 中的每个元素上运行,但仅返回函数返回 true 的元素。
单输出流操作员<T> 过滤器(过滤器功能<T> 过滤器)数据接收器
除了转换数据外,Flink 的主要目的是在将流处理到不同的目的地后引导它们。这些目的地称为"接收器"。Flink 具有内置接收器(文本、CSV、套接字),以及与其他系统(如 Apache Kafka)的开箱即用连接器[2]定义时间戳有三个选项:
处理时间 (默认选项):是指执行流处理操作的计算机的系统时间,因此它是最简单的时间概念;它不需要流和计算机之间的任何协调。由于它基于计算机的时间,因此可提供最佳性能和最低的延迟。
在分布式和异步环境中,使用处理时间的缺点是显著的,因为它不是确定性方法。如果计算机时钟之间存在间隙,则流事件的时间戳可能会不同步;网络延迟还会在事件离开一台计算机到达另一台计算机的时间之间产生间隙。
Java
xxxxxxx
11流恩夫。设置流时间特征(时间特征.处理时间;事件时间:指每个单个事件在输入 Flink 之前在其生成源上接收的时间。事件时间嵌入到事件本身中,可以提取,以便 Flink 可以正确处理它。
由于时间戳不是由 Flink 设置的,因此应该有一个机制来发出事件应处理或不处理的机制;此机制称为水印。本主题超出了此博客文章的范围(因为我想保持简洁);您可以在Flink 文档中找到更多信息。
Java
xxxxxxx
1251流恩夫。设置流时间特征(时间特征.活动时间;3数据流<字符串>数据流
4*流恩夫。读取文件(审核格式,
5数据Dir ,// 事件的代名词
6文件处理模式.PROCESS_CONTINUOUSLY,
71000)。
8新的时间戳提取器());1011// ...更多代码...
1213定义类以从流事件中提取时间戳
14公共类时间戳提取器实现
15分配者具有周期性水印<字符串>|
16公共水印获取电流水印() |18返回新的水印(系统.当前时间米 ()-最大时间帧);
19}
2021
22公共长提取时间戳(字符串str长l) |
23返回输入数据。获取数据对象(str)
1px;"> }
25}
摄取时间:指事件进入Flink的时间;它在源处分配一次,因此被认为比处理时间更稳定,处理时间在开始过程时分配。
引入时间无法处理顺序外事件或延迟数据,因为时间戳是在引入开始后设置的,而不是具有标识延迟事件并根据水标记机制处理延迟事件的功能的事件时间。Java
xxxxxxx
11流恩夫。设置流时间特征(时间特征.摄取时间;您可以在以下链接中阅读更多有关时间戳及其如何影响流处理。
窗口
顾名思义,流是无穷无尽的;因此,处理机制是通过定义帧(例如,基于时间的窗口)。这样,流将分为存储桶进行聚合和分析。窗口定义是
DataStream
对象或其继承器的操作。有几个基于时间的窗口:
翻转窗口(默认配置)
流被划分为等效大小的窗口,没有任何重叠。只要流流,Flink 会基于此固定时间范围连续计算数据。代码实现:
Java
xxxxxxx
11公共所有窗口流<T,时间窗口> 时间窗口全部(时间大小)3基于键的流的翻滚窗口
4公共窗口流<T,键,时间窗口>时间窗口(时间大小)
滑动窗口
由窗口大小和偏移量(何时启动下一个窗口)组成的重叠窗口。这样,可以在给定时间内在多个窗口中处理事件。这就是它在代码中的外观:
Java
xxxxxxx
11滑动时间窗口长度为 1 分钟,触发间隔为 30 秒
2数据流对象。时间窗口(时间.分钟(1次)。秒(30));
会话窗口
包括会话边界下的所有事件此时间范围可以基于已处理的事件进行固定或动态。从理论上讲,如果会话事件之间的间隙小于窗口的大小,则会话永远不会结束。下面的第一个代码段举例说明了基于时间的固定会话(2 秒)。第二个会话窗口实现一个动态窗口,该窗口基于流的事件。
Java
xxxxxxx
11数据流对象。窗口(处理时间会话窗口)。与间隙(时间.秒(2));34定义动态窗口会话,该会话可以由流元素设置
5数据流对象。窗口(事件时间会话窗口)。与动态差距(elem-> |
6// 返回会话间隙,该间隙可以基于流的事件
7}));
全局窗口
将整个流视为单个窗口。