前言
微信搜【Java3y】关注这个朴实无华的男人,点赞关注是对我最大的反对!
文本已收录至我的 GitHub:https://github.com/ZhongFuCheng3y/3y,有 300 多篇原创文章,最近在连载 面试和我的项目 系列!
在前段时间写了一篇《Storm》入门的文章,很多同学给我说:“小孩儿,时代变了”。
最近公司要把 Storm
集群给下线啦,所以咱们都得把 Storm
的工作都改成Flink
。
于是最近入门了一把 Flink
,当初来分享一下Flink
入门的相干常识。
(写下面这一段话的时候,到发文章这个时候曾经过了一个季度了,不好意思,我这篇文章拖了一个季度)
不得不说,Flink 这两年是真的火???? 这篇文章次要讲讲 Flink
入门时一些可能看不太懂的点又或是看官网介绍看不太懂的点(API
我就不细说了,多用用应该都能看懂)。
什么是 Flink?
在 Flink 的官网上,能够把官网文档语言设置为中文,于是咱们能够看到官网是这样介绍的:
下面的图咱们每个字都能看得懂,但连起来就看不懂了。
不论怎么样,咱们能够理解到:Flink 是一个分布式的计算解决引擎
- 分布式:「它的存储或者计算交由 多台服务器上 实现,最初汇总起来达到最终的成果」。
- 实时:处理速度是毫秒级或者秒级的
- 计算:能够简略了解为对数据进行解决,比方荡涤数据(对数据进行规整,取出有用的数据)
基于官网的 一句话介绍 ,咱们就能够 联想出很多货色。
这篇文章能够带你简略认识一下 Flink 的一些根底概念,等你真正用到的时候就能够根据这篇文章来对 Flink 进行入门,当初 Storm 都被很多人给摈弃掉了,那么 Flink优于Storm 的中央有哪些呢?接下来咱们一起来看看 Flink 吧。
什么是有边界和无边界?
Apache Flink 是一个框架和分布式解决引擎,用于在 _无边界和有边界_数据流 上进行有状态的计算。
官网其实也有介绍,但对初学者来说不太好了解,我来 幼儿园化 一下。
大家学到 Flink 了,音讯队列必定有用过吧?那你们是怎么用音讯队列的呢?Producer
生产数据,发给 Broker
,Consumer
生产,完事。
在生产的时候,咱们须要管什么 Producer 什么时候发消息吗?不须要吧。反正来一条,我就解决一条,没故障吧。
这种没有做任何解决的音讯,默认就是 无边界 的。
那有边界就很好了解了:无边界的根底上 加上条件,那就是有边界的。加什么条件呢?比方我要加个工夫:我要生产从 8 月 8 号到 8 月 9 号的数据,那就是有边界的。
什么时候用无边界,什么时候用有边界?那也很好了解。我做数据荡涤:来一条,我解决一条,这种无边界的就好了。我要做数据统计:每个小时的 pv
(page view) 是多少,那我就设置 1 小时的边界,攒着 一小时的数据来解决一次。
在 Flink
上,设置“边界”这种操作叫做开窗口(Windows
),窗口可简略分为两种类型:
- 工夫窗口(
TimeWindows
):依照工夫窗口进行聚合,比方下面所讲得攥着一个小时的数据处理一次。 - 计数窗口 (
CountWindows
):依照指定的 条数 来进行聚合,比方每来了 10 条数据处理一次。
看着就十分人性化(妈妈再也不必放心我须要聚合了)…
不仅如此,在 Flink
应用窗口聚合的时候,还思考到了 数据的准确性 问题。比如说:当初我在 11:06 分
产生了 5
条数据,在 11:07 分
产生了 4 条数据
,我当初是按 每分钟 的维度来进行聚合计算。
实践上来讲:Flink
应该是在 06 分
聚合了 5 条
数据,在 07 分
聚合了 4 条
数据。然而,可能因为网络的提早性等起因,导致 06 分
的 3 条
数据在 07 分
时Flink
才接管到。如果不做任何解决,那 07 分
有可能解决了 7 条
条数据。
某些须要精确后果的场景来说,这就不太正当了。所以 Flink
能够给咱们指定”工夫语义 “,不指定默认是「数据到 Flink 的工夫」Processing Time
来进行聚合解决,能够给咱们指定聚合的工夫以「事件产生的工夫」Event Time
来进行解决。
事件产生的工夫指的就是:日志真正记录的工夫
2020-11-22 00:00:02.552 INFO [http-nio-7001-exec-28] c.m.t.rye.admin.web.aop.LogAspect
尽管指定了聚合的工夫为「事件产生的工夫」Event Time
,但还是没解决 数据乱序 的问题(06 分产生了 5 条数据,实际上 06 分只收到了 3 条,而剩下的两条在 07 分才收到,那此时怎么办呢?在 06 分时该不该聚合,07 分收到的两条 06 分数据怎么办?)
Flink
又能够给咱们设置水位线 (waterMarks
),Flink 意思就是:存在网络提早等状况导致数据接管不是有序,这种状况我都能了解。你这样吧, 依据本身的状况,你能够设置一个「延迟时间」,等提早的工夫到了,我再聚合对立聚合。
比如说:当初我晓得数据有可能会提早一分钟,那我将水位线 waterMarks
设置提早一分钟。
解读:因为设置了「事件产生的工夫」Event Time
,所以 Flink
能够检测到每一条记录产生的工夫,而设置了水位线 waterMarks
设置提早一分钟,等到 Flink
发现 07 分:59 秒
的数据来到了 Flink
,那就确信06 分
的数据都来了(因为设置了 1 分钟提早),此时才聚合 06 分
的窗口数据。
什么叫做有状态?
Apache Flink 是一个框架和分布式解决引擎,用于在_无边界和有边界_数据流上进行 有状态的 计算。
什么是有状态,什么是无状态?
无状态 咱们能够简略认为:每次的执行都 不依赖 上一次或上 N 次的执行后果,每次的执行都是 独立 的。
有状态 咱们能够简略认为:执行 须要依赖 上一次或上 N 次的执行后果,某次的执行须要依赖后面事件的处理结果。
比方,咱们当初要统计文章的浏览 PV
(page view),当初只有有一个点击了文章,在Kafka
就会有一条音讯。当初我要在 流式解决平台 上进行统计,那此时是有状态的还是无状态的?
假如咱们要在 Storm
做,那咱们 可能 将每次的处理结果放到一个“内部存储”中,而后基于这个“内部存储”进行计算(这里咱们不必 Storm Trident
),那此时Storm
是无状态的。
比如说:我存储将每次失去的数据存储到 Redis
中,来一条数据,我就先查一下 Redis 目前的值是多少,跟 Redis
的值和当初的值做一次累加就完事了。
假如要在 Flink
做,Flink
自身 就提供了这种性能给咱们应用,咱们能够依赖 Flink
的“存储”,将每次的处理结果交由 Flink
治理,执行计算的逻辑。
能够简略的认为:Flink自身 就给咱们提供了”存储“的性能,而咱们每次执行是能够依赖 Flink 的”存储”的,所以它是 有状态 的。
那 Flink
是把这些有状态的数据存储在哪的呢?
次要有三个中央:
- 内存
- 文件系统(HDFS)
- 本地数据库
如果假如 Flink
挂了,可能内存的数据没了,磁盘可能存储了局部的数据,那再重启的时候(比方音讯队列会从新拉取),就不怕会丢了或多了数据吗?
看到这里,你可能在会在别的中央看过 Flink
的另外一个比拟闻名的个性:准确一次性
(简略来说就是:Flink
遇到意外事件挂了当前,有什么机制来尽可能保障解决 数据不反复和不失落 的呢)
什么是准确一次性(exactly once)?
家喻户晓,流的语义性有三种:
- 准确一次性(exactly once):有且只有一条,不多不少
- 至多一次(at least once):起码会有一条,只多不少
- 最多一次(at most once):最多只有一条,可能会没有
Flink 实现了 准确一次性,这个准确一次性是什么意思呢?
Flink 的准确一次性指的是:状态 只长久化一次 到最终 的存储介质中(本地数据库 /HDFS…)
以下面的图为例:Source
数据流有以下数字 21,13,8,5,3,2,1,1
,而后在Flink
须要做 累加 操作(求和)
当初解决完 2,1,1
了,所以累加的值是 4
,当初Flink
把累积后的状态 4
曾经 存储起来了(认为后面 2,1,1
这几个数字 曾经齐全 解决过了)。
程序始终往下走,解决了 5,3
,当初累加的值是12
,但当初Flink
还没来得及把 12
存储到最终的介质,此时零碎挂掉了。
Flink 重启后会从新把零碎复原到累加的值是 4
的状态,所以 5,3
得持续计算一遍,程序持续往下走。
看文章有的同学可能会认为:准确一次性指的不是某一段代码 只会执行一次 ,不会执行屡次或不执行。这5
和3
这两个数,你不是反复计算了吗?怎么就准确一次了?
显然,代码只执行一次必定是不可能的嘛。咱们无奈控制系统在哪一行代码挂掉的,你要是在挂的时候,以后办法还没执行完,你还是得从新执行该办法的。
所以,状态 只长久化一次 到最终 的存储介质中(本地数据库 /HDFS),在 Flink 下就叫做 exactly once
(计算的数据可能会反复(无奈防止),但 状态在存储介质 上只会存储一次)。
那么 Flink
是在多长时间存储一次的呢?这个是咱们本人 手动 配置的。
所谓的 CheckPoint
其实就是 Flink
会在指定的时间段上保留状态的信息,假如 Flink
挂了能够将 上一次 状态信息再捞进去,重放还没保留的数据来执行计算,最终实现exactly once
。
那 CheckPonit
是怎么办到的呢?想想咱们在 Kafka
在业务上实现「至多一次」是怎么做的?咱们从 Kafka
把数据拉下来,解决完业务了当前,手动提交 offset
(通知Kafka
我曾经解决完了)
咱们是 做完了 业务规定才将 offset
进行 commit
的,checkponit
其实也是一样的(等拉下来该条数据所有的流程走完,才进行真正的checkponit
)。
问题又来了,那 checkpoint
是怎么晓得拉下来的数据曾经走完了呢?Flink
在流处理过程中插入了 barrier
,每个环节解决到barrier
都会上报,等到 sink
都上报了 barrier
就阐明这次 checkpoint
曾经走完了。
要留神的是,Flink
实现的准确一次性只是保障 外部的状态 是准确一次的,如果想要端到端准确一次,须要端的反对
- 数据源须要可回放,发证故障能够从新读取未确认的数据
Flink
须要把数据存到磁盘介质(不能用内存),产生故障能够复原- 发送源须要反对事务(从读到写须要事务的反对保障中途不失败)
最初
这篇文章对 Flink
做了一次简略的介绍,心愿对大家在入门的时候有所帮忙。后续打算会再写一篇 Flink
文章对 CheckPoint
机制做更加深刻的理解,有趣味的同学能够点个关注第一工夫能接管到。
三歪把【大厂面试知识点】、【简历模板】、【原创文章】全副整顿成电子书,共有 1263 页!点击下方 链接 间接取就好了
- GitHub
- Gitee 拜访更快
PDF 文档的内容 均为手打 ,有任何的不懂都能够间接 来问我