Flink | 基础入门小结

 

目录

Flink概述

Flink架构&基本组件分析

Flink 流处理(Streaming) & 批处理(Batch)

Flink 如何有效地准确地进行流处理之对时间的处理

Flink 如何有效地准确地进行流处理之有状态的计算


 

浏览完Flink基础教程&入门实践后对Flink有了一个简单的了解,梳理下主要内容知识点

 

为何选择Flink & 为何不选择Flink (洗脑洗脑)

 

Flink概述


Flink 是为分布式、高性能、随时可用以及准确的流处理应用程序打造的开源流处理框架。特性如下:


1、流式优先:可以连续处理流式数据;
2、容错:提供有状态的计算,可以记录数据的处理状态,当数据处理失败时,能够无缝地从失败中恢复,并保持Exactly-Once;
3、可伸缩:分布式集群
4、性能:高吞吐、低延迟。即支持快速地处理海量数据,高吞吐标识单位时间内可以处理的数据量很大,低延迟表示数据产生后在很短的时间内就能将其处理完毕。


Flink架构&基本组件分析
 

                      

Flink技术栈有四个核心组成部分,分别为Deploy层、Core层、API层和Library层。
Deploy层:主要涉及Flink的部署模式,Flink支持多种部署模式。eg:本地、集群等;

Core:提供了支持Flink计算的全部核心实现,为API层提供基础服务;

API层:Flink 分别提供了面向流处理的接口(DataStream API)和面向批处理的接口(DataSet API),(流&批统一:Flink 将批处理(即处理有限的静态数据)视作一种特殊的流处理);

Library层:Flink应用框架层,支持的拓展库涉及机器学习(FlinkML)、复杂事件处理(CEP),以及图计算(Gelly),还有分别针对流处理和批处理的Table API;

另外在Flink中还提供了以下3个组件:

DataSource:表示数据源组件,主要用来接收数据,目前官网提供了readTextFile、socketTextStream、fromCollection以及一些第三方的Source。
Transformation:表示算子,主要用来对数据进行处理,比如Map、FlatMap、Filter、Reduce、Aggregation等。
DataSink:表示输出组件,主要用来把计算的结果输出到其他存储介质中,比如writeAsText以及Kafka、Redis、Elasticsearch等第三方Sink组件。

Flink Job = DataSource + Transformation + DataSink


Flink 流处理(Streaming) & 批处理(Batch)

Flink 是如何同时实现批处理与流处理的呢?

答案是,Flink 将批处理(即处理有限的静态数据)视作一种特殊的流处理。即流批统一。(NP~~~)

如何有效地实现流处理架构并从 Flink 中获益呢?

一个常见的做法是设置消息传输层和流处理层
(1) 消息传输层从各种数据源(生产者)采集连续事件产生的数据,并传输给订阅了这些数据的应用程序和服务(消费者)。


(2) 流处理层有 3 个用途:①持续地将数据在应用程序和系统间移动;②聚合并处理事件;③在本地维持应用程序的状态。

 

消息传输层:从各个数据生产者中采集连续事件的数据,并传输给订阅了这些数据的消费者,常见的消息传输层技术有Kafka和MapR Streams.

这一层中维护了一个事件数据的安全队列,产生的消息可以被保留起来,也可以重播给流处理层。在复杂系统中,消息传输层往往对应了多个生产者与多个消费者,生产者负责生产数据,消费者负责消费数据,两者相互解耦,即生产者生产消息后,不是由生产者向所有的消费者广播,而是消费者从消息队列中订阅消息,消息到达后,消费者并不一定需要在运行状态,即消息达到后并不一定立刻被处理,具体处理时间可由消费者根据自身业务逻辑指定。

流处理层:聚合并处理事件;持续地将数据在应用程序与各系统间移动;应用程序的数据状态本地化。

 

流式处理计算框架的对比 ?

在大数据处理领域,批处理与流处理一般被认为是两种截然不同的任务,一个大数据框架一般会被设计为只能处理其中一种任务。比如,Storm只支持流处理任务,而MapReduce、Spark只支持批处理任务。Spark Streaming是Apache Spark之上支持流处理任务的子系统,这看似是一个特例,其实不然——Spark Streaming采用了一种Micro-Batch架构,即把输入的数据流切分成细粒度的Batch,并为每一个Batch数据提交一个批处理的Spark任务,所以Spark Streaming本质上还是基于Spark批处理系统对流式数据进行处理,和Storm等完全流式的数据处理方式完全不同。

 

                    


接下来应该是Flink的重要点了,先了解下

Flink 如何有效地准确地进行流处理之对时间的处理

时间概念

在流处理中,主要有3个时间概念,如下:

事件时间:即事件实际发生的时间。更准确的说是每一个事件都有一个与它相关的时间戳,而事件事件其实就是时间戳。

处理时间:即事件被处理的事件。

摄取时间:又称为进入时间,即事件进入流处理框架的时间。缺乏真实事件事件的数据会被流处理器附上时间戳,即流处理器第一次看到它的时间。

在Flink中基于时间定义孕育用户根据所需的语义和对准确性的要求选择采用事件时间、处理时间或摄取时间定义窗口。

例如: 当采用事件时间定义窗口时,应用程序可以处理乱序事件流以及变化的事件时间偏差,并根据事件实际发生的时间计算出有意义的结果。

窗口?什么是窗口?

窗口是一种机制,它用于将许多事件按照时间或者其他特征分组,从而将每一组作为整体进行分析(比如求和)。

时间窗口:最简单和最有用的一种窗口。它支持滚动和滑动。举一个例子,假设要对传感器输出的数值求和。

一分钟滚动窗口的定义:stream.timeWindow(Time.minutes(1))

每半分钟(即 30 秒)滑动一次的一分钟滑动窗口定义:stream.timeWindow(Time.minutes(1), Time.seconds(30))

计数窗口:分组依据不再是时间戳,而是元素的数量。滚动和滑动的计数窗口分别定义如下:

stream.countWindow(4)
stream.countWindow(4, 2)

会话窗口:会话指的是活动阶段,其前后都是非活动阶段,例如用户与网站进行一系列交互(活动阶段)之后,关闭浏览器或者不再交互(非活动阶段)。会话需要有自己的处理机制,因为它们通常没有固定的持续时间(有些 30 秒就结束了,有些则长达一小时),或者没有固定的交互次数(有些可能是 3 次点击后购买,另一些可能是 40 次点击却没有购买)。

如果用户处于非活动状态长达 5 分钟,则认为会话结束。示例如下:
stream.window(SessionWindows.withGap(Time.minutes(5))

触发器:触发器控制生成结果的时间,即何时聚合窗口内容并将结果返回给用户。每一个默认窗口都有一个触发器。

例如,采用事件时间的时间窗口将在收到水印时被触发。对于用户来说,除了收到水印时生成完整、准确的结果之外,也可以实现自定义的触发器

 

什么是时空穿梭?

流处理架构的一个核心能力是时空穿梭(即重新处理数据)。

流处理器支持事件时间,这意味着将数据流“倒带”,用同一组数据重新运行同样的程序,会得到相同的结果。
若要按时间回溯并正确地重新处理数据,流处理器必须支持事件时间。

如果窗口的设定是根据系统时间而不是时间戳,那么每次运行同样的程序,都会得到不同的结果。事件时间使数据处理结果具有确定性,因为用同一组数据运行同样的程序,会得到相同的结果。

如果所有的数据处理工作都由流处理器完成,那么应用程序如何演进呢?我们如何处理历史数据,又如何重新处理数据呢?


如图所示,时空穿梭意味着将数据流倒回至过去的某个时间,重新启动处理程序,直到处理至当前时间为止。

像 Kafka 和 MapR Streams 这样的现代传输层,支持时空穿梭,这使得它们与更早的解决方案有所区别。实时流处理总是在处理最近的数据(即图中“当前时间”的数据),历史流处理则从过去开始,并且可以一直处理至当前时间。

 

什么是水印?

支持事件时间对于流处理架构而言至关重要,因为事件时间能保证结果正确,并使流处理架构拥有重新处理数据的能力。当计算基于事件时间时,如何判断所有事件是否都到达,以及何时计算和输出窗口的结果呢?换言之,如何追踪事件时间,并知晓输入数据已经流到某个事件时间了呢?为了追踪事件时间,需要依靠由数据驱动的时钟,而不是系统时钟。

Flink 通过水印来推进事件时间。

水印是嵌在流中的常规记录,计算程序通过水印获知某个时间点已到。假设水印标记时间为 10:01:00,那么收到水印的窗口就知道不会再有早于该时间的记录出现,因为所有时间戳小于或等于该时间的事件都已经到达。这时,窗口可以安全地计算并给出结果(总和)。

水印使事件时间与处理时间完全无关。迟到的水印(“迟到”是从处理时间的角度而言)并不会影响结果的正确性,而只会影响收到结果的速度。

水印是如何生成的?


在 Flink 中,水印由应用程序开发人员生成,这通常需要对相应的领域有一定的了解。

完美的水印永远不会错:时间戳小于水印标记时间的事件不会再出现。在特殊情况下(例如非乱序事件流),最近一次事件的时间戳就可能是完美的水印。

启发式水印则相反,它只估计时间,因此有可能出错,即迟到的事件(其时间戳小于水印标记时间)晚于水印出现。针对启发式水印,Flink 提供了处理迟到元素的机制。

设定水印通常需要用到领域知识。

举例来说,如果知道事件的迟到时间不会超过 5 秒,就可以将水印标记时间设为收到的最大时间戳减去 5 秒。

另一种做法是,采用一个 Flink 作业监控事件流,学习事件的迟到规律,并以此构建水印生成模型。


水印为以事件时间说明输入数据的完整性提供了一种机制,这种机制可能是启发式的。如果水印迟到得太久,收到结果的速度可能就会很慢,解决办法是在水印到达之前输出近似结果(Flink 可以实现)。如果水印到达得太早,则可能收到错误结果,不过 Flink 处理迟到数据的机制可以解决这个问题。

上述问题看起来很复杂,但是恰恰符合现实世界的规律——大部分真实的事件流都是乱序的,并且通常无法了解它们的乱序程度(因为理论上不能预见未来)。水印是唯一让我们直面乱序事件流并保证正确性的机制;否则只能选
择忽视事实,假装错误的结果是正确的。


Flink 如何有效地准确地进行流处理之有状态的计算

流式计算分为无状态和有状态两种情况。

无状态:观察每个独立事件,并根据最后一个事件输出结果

有状态:基于多个事件输出结果,维护了每个独立事件对输出结果的状态(即影响),最终基于最新一个事件与当前状态输出结果。



如上图展示了无状态流处理和有状态流处理的主要区别。无状态流处理分别接收每条记录(图中的黑条),然后根据最新输入的记录生成输出记录(白条)。有状态流处理会维护状态(根据每条输入记录进行更新),并基于最新输入的记录和当前的状态值生成输出记录(灰条)。

 

Flink如何保证Exactly-Once?

at-most-once:这其实是没有正确性保障的委婉说法——故障发生之后,计数结果可能丢失。
at-least-once:这表示计数结果可能大于正确值,但绝不会小于正确值。即数程序在发生故障后可能多算,但是绝不会少算。
exactly-once:指的是系统保证在发生故障后得到的计数结果与正确值一致。
 

Flink 如何保证 exactly-once 呢?它使用一种被称为“检查点”的特性,在出现故障时将系统重置回正确状态。

 

什么是检查点?

检查点可以保证Flink实现exactly-once。

检查点是指每隔一段时间(程序自定义),系统会保存事件的位置以及事件计算的中间状态,在故障发生重启后,直接定位到发生故障时事件的位置,并从对应的事件计算的中间状态开始计算。

如果检查点保存失败,Flink会丢弃该检查点并继续计算,到下一个检查点再保存,如果一系列连续的检查点都失败,那么Flink会判断这个任务是失败的。
 

检查点由 Flink 自动生成,用来在故障发生时重新处理记录,从而修正状态。

Flink 检查点算法的正式名称是异步屏障快照(asynchronous barrier snapshotting)。该算法大致基于 Chandy-Lamport 分布式快照算法。

检查点是 Flink 最有价值的创新之一,因为它使 Flink 可以保证 exactly-once,并且不需要牺牲性能。

什么是保存点?

设置好检查点时间间隔后,检查点是Flink自动生成的,而Flink提供了用户可手动触发状态保存的接口,那就是保存点,用户可以通过Flink命令行工具或Web控制台手动触发。

保存点与检查点背后工作方式完全相同。只不过它由用户通过 Flink 命令行工具或者 Web 控制台手动触发,而不由 Flink 自动触发。和检查点一样,保存点也被保存在稳定存储中。用户可以从保存点重启作业,而不用从头开始。

保存点可以被视为作业在某一个特定时间点的快照(该时间点即为保存点被触发的时间点)。


对保存点的另一种理解是,它在明确的时间点保存应用程序状态的版本。这和用版本控制系统保存应用程序的版本很相似。

最简单的例子是在不修改应用程序代码的情况下,每隔固定的时间拍快照,即照原样保存应用程序状态的版本。


 

更多学习:

https://ververica.cn/developers/flink-basic-tutorial-1-basic-concept/

http://www.imooc.com/article/278651
 

 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值