流式处理新秀Flink原理与实践
随着大数据技术在各行各业的广泛应用,要求能对海量数据进行实时处理的需求越来越多,同时数据处理的业务逻辑也越来越复杂,传统的批处理方式和早期的流式处理框架也越来越难以在延迟性、吞吐量、容错能力以及使用便捷性等方面满足业务日益苛刻的要求。
在这种形势下,新型流式处理框架Flink通过创造性地把现代大规模并行处理技术应用到流式处理中来,极大地改善了以前的流式处理框架所存在的问题。飞马网于3月13日晚,邀请到大数据技术高级架构师-旷东林,在线上直播中,旷老师向我们分享了Flink在诸多方面的创新以及它本身所具有的独特能力。
我们主要从以下几个部分来看:
一.流式处理的背景:
传统的大数据处理方式一般是批处理式的,也就是说,今天所收集的数据,我们明天再把今天收集到的数据算出来,以供大家使用,但是在很多情况下,数据的时效性对于业务的成败是非常关键的。
1.流式处理的背景-必要性
比如说,在***检测的场景下,我们希望看到的结果是:一旦有***,我们能及时地作出响应。这种情况下,如果按照传统的批处理方式,是不可能在***的时候实时检测出结果的。另外,比如说在语音计算中,我们要实时监控各个虚拟器的运行状态以及出现错误时的预警,这种情况下,也要求我们能够实时监控数据,并对数据产生的各种报警,实时采取动作。由此,流式处理的必要性就显得无疑了。
2.流式处理的背景-基础架构
我们来看一下流式处理的基本框架。
主要分为六个部分:事件生产者、收集、排队系统(其中kafka的主要目的是,在数据高峰时,暂时把它缓存,防止数据丢失。)、数据变换(也就是流式处理过程)、长期存储、陈述/行动。
3.流式处理的背景-评测指标
目前的业界有很多流式处理的框架,在这么多框架中,我们怎样评价这个流式处理框架的性能呢?有哪些指标呢?一般我们会从以下这些方面来考核流式处理框架的能力。
其中"数据传输的保障度",是指能不能保证数据被处理并到达目的地。它有三种可能性:保证至少一次、最多一次、精确一次。大多数情况下,"保证至少一次"就能满足业务要求,除要求数据精确度高的特定场景。
"处理延迟",在大多数情况下,流式处理的延迟越低越好,但很多情况下,我们的延迟越低,相应付出的代价也越高,"吞吐量"与"处理延迟"就是一对矛盾。吞吐量高,相应的延迟就会低,吞吐量低,相应的延迟就会高。
"状态管理",我们在实时变换的过程中,要有与外部的交互,如***检测,以此来保护环境和数据的安全。
"容错能力"和"容错负荷"要求当流式处理在正常进行中,即使有某些机器挂掉,系统仍能正常运行,整个流式处理框架不受影响。
"流控",也就是流量控制,我们在数据传输的过程中,可能会数据突然增多,为了保证系统不至于负荷过重而崩溃,这时候就需要控制数据密度。
"编程复杂性",相对而言,API设计地越高级,编程负担越低。
4.流式处理的背景-选型
了解流式处理框架的考核标准之后,那么我们为什么选择Flink?Flink有哪些优势呢?
"保证带状态计算下的精确一次语义",对于某些特定的计算而言非常有必要。
一般在流式处理框架中,数据的处理一般有两种方式,一种是按照处理时间来处理数据,另一种就是按照事件时间来处理数据,"事件时间语义支持"方式更为复杂。
Flink的API非常高级,在处理流式数据的逻辑业务中,效率更高。
二.Flink的原理:
了解Flink的背景之后,我们一起来看一看它的原理。
1.概述
Flink的整个组件类似于Spark,它的核心是一个分布式的流式处理框架,在核心之上,有两套API,一套应用于批处理-DataSet API,一套应用于流式处理-DataStream API。
从图中我们可以看到,在两套API下又有更为高级的库,而它的整个处理部署方式可以支持本地、集群、云端。
2.基础架构
Flink的整个架构和Spark很相似,有三个主要部分。
一个是提交任务的客户端-Flink Program;还有作业的管理器-JobManager,主要负责任务的调度和状态的检测,以及在整个集群出现故障时进行初步管理;最后是任务管理器-TaskManager,实现业务逻辑的执行,负责把接受到的任务运行之后,将相应的结果输出到外部或进行外部交互。
在整个过程中,JobManager是不负责任务执行的。
3.编程模型
下面我们来看一下Flink的具体编程模型结构。
第一条语句是建立整个Flink运行时的环境,类似于Spark里建立一个上下文。它的主要业务逻辑是由指定数据源、指定变换逻辑、指定输出三部分决定的。
指定数据源的过程就是nv.addSource,这是指定我们的数据到底从哪里来,在这个设计中,它是从kafka里把数据读出来。在这个事例里面,数据流的变换比较简单,只是把每一行数据做一个解析,解析完后获得另一个数据流,就构成了 DataStreamevents这个数据流。
在这个数据流上面,我们做了一个分组:keyBy("id")、timeWindow(Time.seconds(10))、apply(new MyWindowAggregationFunction())。我们把整个数据处理完之后,得到一个统计数据流,指定输出。
这大致就是整个数据流的业务逻辑,箭头下方是数据流图。
示例里面展示的只是部分API,除了上面那些,还有很多操作,我们一起来看下面这张图片。
"map"就是做一些映射,比如我们把两个字符串合并成一个字符串,把一个字符串拆成两个或者三个字符串。
"flatMap"类似于把一个记录拆分成两条、三条、甚至是四条记录。
"Filter"就类似于过滤。
"keyBy"就等效于SQL里的group by。
"reduce"就类似于MapReduce里的reduce。
"join"操作就有点类似于我们数据库里面的join。
"aggregate"是一个聚合操作,如计数、求和、求平均等。
"connect"实现把两个流连成一个流。
"project"操作就类似于SQL里面的snacks。
"repartition"是一个重新分区操作。
4.执行机制
知道Flink的编程模型之后,那么Flink是怎样去运行这些业务逻辑的呢?下面是它的执行机制。
上图是表现业务逻辑的业务执行图,Flink的执行方式类似于管道,它借鉴了数据库的一些执行原理,实现了自己独特的执行方式。
5.状态与容错
Flink的容错机制很特别,我们一起来看一看。
Flink在处理数据流时,它的整个数据流里面的数据分为两种,一种是本身业务发给的数据,还有一种是Flink自己插到数据流里面的数据。插入的记录我们叫它barrier,就是栅栏,我们可以把它看成一个表示进度的标记,标记整个数据处理的状态,它从源头发出。从图中我们可以看到,不管是什么流,它都会产生一个checkpoint barrier。
当operator收到栅栏之后,它会把栅栏的状态存储,然后把特定记录发出去,到达第二个operator里面,它又把它的状态放到Master里,它就是这样一步一步去完成的。在这个过程中,如果有一步出现故障,Flink会重复前面的步骤,重新去运行,所以不会出现数据的丢失和错误。
三.Flink的实践:
1.示例
我们来看一下具体的示例。
第一步是初始化框架的运行时环境;第二步是指定数据流的数据源,示例里指定的是FlinkKafkaConsumer010<>(...)数据;第三步是实现数据流的业务变换逻辑,这里主要是通过flatmap把一个记录分成多条记录,通过filter进行过滤,之后按照域名进行分组,指定窗口长度,最后指定统计方式,这里的统计方式是计数;第四步就是对统计出来的数据流进行指定输出;最后一步,提交数据变换逻辑到框架中经编译后运行。
2.监控
把这个程序启动之后,我们就可以看到Flink的监控页面,下面是一些监控信息。
我们可以看到,在启动的Flink集群里面,有80个Task Managers,80个巢,1个空闲的巢数,红框点进去之后,就是下面的图片。
监控指标有很多。
四.总结与展望:
最后,我们来做一下总结。以上只是关于Flink的一些简单介绍,关于Flink的内存管理、部署、内部执行机制等相关详细资料,我们可以通过以下网站进行资料查询。
Apache Flink是有关Flink开源的官方网站。
Flink-Forward网站主要介绍各家大公司在使用Flink过程中的心得体会,以及Flink本身的发展提案的一些相关内容。
dataArtisans是Flink背后的一个商业公司,Flink由它发展起来。它上面的博客包含好多关于Flinkd的介绍,以及一些有深度的文章。
Athenax主要是关于Flink的前瞻×××的网站。
以上四部分就是本次线上直播旷东林老师讲述的主要内容,在提问环节有哪些问题呢?我们一起来看看。
1.请老师讲讲Flink和最新版Spark的对比?
旷老师:spark streaming和flink是竞争关系,两个框架都是流处理里面用的比较多,Flink最大的优势在于保证高吞吐量情况下的低延迟,以及对复杂的带有状态的流的状态管理能力,还有就是非常灵活窗口的支持。
2.新版spark采用的是timeline db技术吗?
旷老师:不是的,timeline db在实现上与spark不是一样的,spark streaming是典型的微批次的流处理框架,其他的大部分都是基于pipeline的执行架构。
这次线上直播,相信大家对Flink流式处理有了进一步的认识,在这里我们也很感谢旷东林老师的分享。想了解更多更详细内容的小伙伴们,可以关注服务号:FMI飞马网,点击菜单栏飞马直播,即可进行学习。