大家好,欢迎来到IT知识分享网。
第1章 为何选择Flink
Apache Flink 是为分布式、高性能、随时可用以及准确的流处理应用程序打造的开源流处理框架。Flink不仅能提供同时支持高吞吐和exactly-once 语义的实时计算,还能提供批量数据处理。
Flink 将批处理(即处理有限的静态数据)视作一种特殊的流处理。Flink 分别提供了面向流处理的接口(DataStream API)和面向批处理的接口(DataSet API)。因此,Flink 既可以完成流处理,也可以完成批处理。Flink 支持的拓展库涉及机器学习(FlinkML)、复杂事件处理(CEP),以及图计算(Gelly),还有分别针对流处理和批处理的Table API。
第2章 流处理架构
2.2 消息传输层和流处理层
如何有效地实现流处理架构并从Flink 中获益呢?一个常见的做法是设置消息传输层和流处理层。
- 消息传输层:从各种数据源(生产者)采集连续事件产生的数据,并传输给订阅了这些数据的应用程序和服务(消费者)。
- 流处理层有3个用途:①持续地将数据在应用程序和系统间移动;②聚合并处理事件;③在本地维持应用程序的状态。
2.3 消息传输层的理想功能
2.3.1 兼具高性能和持久性
消息传输层的一个作用是作为流处理层上游的安全队列——它相当于缓冲区,可以将事件数据作为短期数据保留起来,以防数据处理过程发生中断。具有持久性的好处之一是消息可以重播。
2.3.2 将生产者和消费者解耦
采用高效的消息传输技术,可以从多个源(生产者)收集数据,并使这些数据可供多个服务或应用程序(消费者)使用。数据源将数据推送给消息队列,消费者(或消费者群组)则拉取数据。
2.4 支持微服务架构的流数据
微服务方法指的是将大型系统的功能分割成通常具有单一目的的简单服务,从而使小型团队可以轻松地构建和维护这些服务。
2.4.1 数据流作为中心数据源
流处理架构不需要集中式数据库。取而代之的是消息队列,它作为共享数据源,服务于各种不同的消费者。
第4章 对时间的处理
4.1 采用批处理架构和Lambda架构
用定期运行的批处理作业来实现应用程序的持续性存在以下问题。
- 太多独立的部分。这种架构动用了太多系统,每一个系统都有学习成本和管理成本。
- 对时间的处理方法不明确。
- 预警。Lambda 架构:流处理器实时提供近似结果;批处理层最终会对近似结果予以纠正。但是这样一来,就向架构增加了一个系统,以及与之相关的新编程模型。
- 乱序事件流。即事件的实际发生顺序和数据中心所记录的顺序不一样。
- 批处理作业的界限不清晰。在该架构中,“每小时”的定义含糊不清,分割时间点实际上取决于不同系统之间的交互。
4.2 采用流处理架构
事件流由消息传输系统提供,并且只被单一的Flink 作业处理,以时间为单位把事件流分割为一批批任务(称作窗口),这种逻辑完全嵌入在Flink 程序的应用逻辑中。要从以固定时间分组改为根据产生数据的时间段分组,只需在Flink 程序中修改对窗口的定义即可。
4.3 时间概念
在流处理中,有三个时间概念。
- 事件时间,即事件实际发生的时间。更准确地说,每一个事件都有一个与它相关的时间戳,并且时间戳是数据记录的一部分。
- 处理时间,即事件被处理的时间。处理时间其实就是处理事件的机器所测量的时间。
- 摄取时间,也叫作进入时间。它指的是事件进入流处理框架的时间。
4.4 窗口
窗口是一种机制,它用于将许多事件按照时间或者其他特征分组,从而将每一组作为整体进行分析。
4.4.1 时间窗口
时间窗口是最简单和最有用的一种窗口。它支持滚动和滑动。
4.4.2 计数窗口
Flink 支持的另一种常见窗口叫作计数窗口。采用计数窗口时,分组依据不再是时间戳,而是元素的数量。
4.4.3 会话窗口
会话指的是活动阶段,其前后都是非活动阶段。在Flink 中,会话窗口由超时时间设定,即希望等待多久才认为会话已经结束。
4.4.4 触发器
除了窗口之外,Flink 还提供触发机制。触发器控制生成结果的时间,即何时聚合窗口内容并将结果返回给用户。
4.4.5 窗口的实现
- 开窗机制与检查点机制完全分离。这意味着窗口时长不依赖于检查点间隔。事实上,窗口完全可以没有“时长”(比如计数窗口和会话窗口的例子)。
- 高级用户可以直接用基本的开窗机制定义更复杂的窗口形式(如某种时间窗口,它可以基于计数结果或某一条记录的值生成中间结果)。
4.5 时空穿梭
时空穿梭意味着将数据流倒回至过去的某个时间,重新启动处理程序。若要按时间回溯并正确地重新处理数据,流处理器必须支持事件时间。如果窗口的设定是根据系统时间而不是时间戳,那么每次运行同样的程序,都会得到不同的结果。事件时间使数据处理结果具有确定性,因为用同一组数据运行同样的程序,会得到相同的结果。
4.6 水印
为了追踪事件时间,需要依靠由数据驱动的时钟,而不是系统时钟。Flink 通过水印来推进事件时间。水印是嵌在流中的常规记录,计算程序通过水印获知某个时间点已到。在Flink 中,水印由应用程序开发人员生成。时间戳小于水印标记时间的事件不会再出现。
第5章 有状态的计算
流式计算分为无状态和有状态两种情况。无状态的计算观察每个独立事件,并根据最后一个事件输出结果。有状态的计算则会基于多个事件输出结果。
5.2 检查点:保证exactly-once
Flink 如何保证exactly-once 呢?它使用一种被称为“检查点”的特性,在出现故障时将系统重置回正确状态。Flink 检查点算法的正式名称是异步屏障快照(asynchronous barrier snapshotting)。该算法大致基于Chandy-Lamport 分布式快照算法。
检查点屏障和普通记录类似。它们由算子处理,但并不参与计算,而是会触发与检查点相关的行为。检查点屏障像普通记录一样在算子之间流动,它将其在输入流中的位置以异步的方式保存到稳定存储中(Flink 的存储机制是插件化的,稳定存储可以是分布式文件系统)。当算子的状态备份和检查点屏障的位置备份被确认之后,该检查点操作就可以被标记为完成。
如果检查点操作失败,Flink 会丢弃该检查点并继续正常执行,因为之后的某一个检查点可能会成功。虽然恢复时间可能更长,但是对于状态的保证依旧很有力。只有在一系列连续的检查点操作失败之后,Flink 才会抛出错误,因为这通常预示着发生了严重且持久的错误。
5.3 保存点:状态版本控制
Flink 用户还可以通过保存点(savepoint)特性有意识地管理状态版本。保存点与检查点的工作方式完全相同,只不过它由用户通过Flink 命令行工具或者Web 控制台手动触发,而不由Flink 自动触发。和检查点一样,保存点也被保存在稳定存储中。用户可以从保存点重启作业,而不用从头开始。保存点可以被视为作业在某一个特定时间点的快照(该时间点即为保存点被触发的时间点)。
可以从保存点启动被修改过的程序版本。新版本可以从旧版本生成的一个保存点处开始执行。保存点可用于应对流处理作业在生产环境中遇到的许多挑战。
- 应用程序代码升级:通过触发保存点并从该保存点处运行新版本,下游的应用程序并不会察觉到不同(当然,被更新的部分除外)。
- Flink 版本更新:Flink 自身的更新也变得简单,因为可以针对正在运行的任务触发保存点,并从保存点处用新版本的Flink 重启任务。
- 维护和迁移:使用保存点,可以轻松地“暂停和恢复”应用程序。这对于集群维护以及向新集群迁移的作业来说尤其有用。此外,它还有利于开发、测试和调试,因为不需要重播整个事件流。
- 假设模拟与恢复:在可控的点上运行其他的应用逻辑,以模拟假设的场景,这样做在很多时候非常有用。
- A/B 测试:从同一个保存点开始,并行地运行应用程序的两个版本,有助于进行A/B 测试。
5.4 端到端的一致性和作为数据库的流处理器
在将状态内容传送到输出存储系统的过程中,如何保证exactly-once 呢?这叫作端到端的一致性。本质上有两种实现方法,用哪一种方法则取决于输出存储系统的类型,以及应用程序的需求。
- 第一种方法是在sink 环节缓冲所有输出,并在sink 收到检查点记录时,将输出“原子提交”到存储系统。这种方法保证输出存储系统中只存在有一致性保障的结果,并且不会出现重复的数据。从本质上说,输出存储系统会参与Flink 的检查点操作。要做到这一点,输出存储系统需要具备“原子提交”的能力。
- 第二种方法是急切地将数据写入输出存储系统,同时牢记这些数据可能是“脏”的,而且需要在发生故障时重新处理。如果发生故障,就需要将输出、输入和Flink 作业全部回滚,从而将“脏”数据覆盖,并将已经写入输出的“脏”数据删除。注意,在很多情况下,其实并没有发生删除操作。例如,如果新记录只是覆盖旧纪录(而不是添加到输出中),那么“脏”数据只在检查点之间短暂存在,并且最终会被修正过的新数据覆盖。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/6278.html