不同的Flink入门教程

前言

微信搜【Java3y】关注这个朴实无华的男人,点赞关注是对我最大的支持!git

文本已收录至个人GitHubhttps://github.com/ZhongFuCheng3y/3y,有300多篇原创文章,最近在连载面试和项目系列!github

在前段时间写了一篇《Storm》入门的文章,不少同窗给我说:“大人,时代变了”。web

最近公司要把Storm集群给下线啦,因此咱们都得把Storm的任务都改为Flink面试

因而最近入门了一把Flink,如今来分享一下Flink入门的相关知识。数据库

(写上面这一段话的时候,到发文章这个时候已通过了一个季度了,很差意思,我这篇文章拖了一个季度)服务器

不得不说,Flink这两年是真的火🔥这篇文章主要讲讲Flink入门时一些可能看不太懂的点又或是看官方介绍看不太懂的点(API我就不细说了,多用用应该都能看懂)。微信

什么是Flink?

在Flink的官网上,能够把官方文档语言设置为中文,因而咱们能够看到官方是这样介绍的:网络

上面的图咱们每一个字都能看得懂,但连起来就看不懂了。框架

无论怎么样,咱们能够了解到:Flink是一个分布式的计算处理引擎分布式

  • 分布式:「它的存储或者计算交由多台服务器上完成,最后汇总起来达到最终的效果」。

  • 实时:处理速度是毫秒级或者秒级的

  • 计算:能够简单理解为对数据进行处理,好比清洗数据(对数据进行规整,取出有用的数据)

基于官网的一句话介绍,咱们就能够联想出不少东西

这篇文章能够带你简单认识一下Flink的一些基础概念,等你真正用到的时候就能够依据这篇文章来对Flink进行入门,如今Storm都被不少人给抛弃掉了,那么Flink优于Storm的地方有哪些呢?接下来咱们一块儿来看看Flink吧。

什么是有边界和无边界?

Apache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。

官方其实也有介绍,但对初学者来讲不太好理解,我来幼儿园化一下。

你们学到Flink了,消息队列确定有用过吧?那大家是怎么用消息队列的呢?Producer生产数据,发给BrokerConsumer消费,完事。

在消费的时候,咱们须要管什么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得继续计算一遍,程序继续往下走。

看文章有的同窗可能会认为:精确一次性指的不是某一段代码只会执行一次,不会执行屡次或不执行。这53这两个数,你不是重复计算了吗?怎么就精确一次了?

显然,代码只执行一次确定是不可能的嘛。咱们没法控制系统在哪一行代码挂掉的,你要是在挂的时候,当前方法还没执行完,你仍是得从新执行该方法的。

因此,状态只持久化一次最终的存储介质中(本地数据库/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页!点击下方连接直接取就行了

PDF文档的内容均为手打,有任何的不懂均可以直接来问我

相关文章
相关标签/搜索