`
Flink介绍
1.1 Flink引入
这几年大数据的飞速发展,出现了很多热门的开源社区,其中著名的有Hadoop、Storm,以及后来的 Spark,他们都有着各自专注的应用场景。Spark掀开了内存计算的先河,也以内存为赌注,赢得了内存计算的飞速发展。Spark 的火热或多或少的掩盖了其他分布式计算的系统身影。就像 Flink,也就在这个时候默默的发展着。
nbsp; 在国外一些社区,有很多人将大数据的计算引擎分成了4 代,当然也有很多人不会认同。我们先姑且这么认为和讨论。
-
第一代---- Hadoop MapReduce
-
批处理
-
Mapprer,Reducer
Hadoop 的Mapreduce将计算分为两个阶段,分别为Map和Reduce,对于上层应用来说,
就不得不想方设法的去拆分算法,甚至于不得不在上层应用实现多个job的串联,以完成一个完整的算法
-
-
第二代----DAG框架(Tez)+MapReduce
- 批处理
- 1个Tez=MR(1)+MR(2)+…+MR(N)
- 相比MR效率有所提升
-
第三代----Spark
- 批处理,流处理,SQL高层API支持
- 自带DAG
- 内存迭代计算,性能较之前大幅提升
-
第四代----flink
- 批处理,流处理,SQL高层API支持
- 自带DAG
- 流式计算性能更高,可靠性更高
1.2 什么是Flink
Flink概述:
- 分布式的计算引擎
- 支持批处理,即处理静态的数据集,历史的数据集
- 支持流处理,即实时的处理一些实时数据流
- 支持基于书剑的应用[比如滴滴通过Flink CEP 实现实时监测司机的行为流来判断司机的行为是否正当]
官网地址 : https://flink.apache.org/
logo介绍
在德语中,Flink一词表示快速和灵巧,松鼠具有快速和灵巧的特点
帕林的松鼠是红棕色的,Flink的松鼠logo尾巴的颜色与Apache基金会的logo颜色相呼应
官网介绍
- Data streams ,Flink认为有界数据集是无界数据流的一种特例,所以说有界数据集也是一种数据流,事件流也是一种数据流,Everything is streams,即Filnk可以用来处理任何的数据,可以支持批处理,流处理,AI等
- Stateful Computations,即有状态计算,有状态计算是最近几年来越来越被用户需求的一个功能,比如一个网站一天访问UV数,那么这个UV就是状态,Flink提供了内置的对状态的一致性的处理,即如果任务发生了Failover,其状态不会丢失,不会被多算少算,同时提供了非常高的性能
无界流:意思很明显,只要开始没有结束,必须连续的处理无界流的数据,也即是事件在注入之后立即要对其进行处理,不能等待数据达到了在去全部处理,因为数据是无界的并且拥有不会结束注入,处理无界流数据往往要求注入的时候有一定的顺序性,例如可以以时间产生的顺序注入,这样会使得结果处理完整
有界流:也即是由明确的开始和结束的定义,有界流可以等待数据全部注入后在开始处理,注入的顺序不是必须的,有界流的处理也成为批处理
1.3 性能比较
首先,我们可以通过下面的性能测试初步了解两个框架的性能区别,它们都可以基于内存计算框架进行实时计算,所以都拥有非常好的计算性能。经过测试,Flink计算性能上略好。
测试环境:
1.CPU:7000个;
2.内存:单机128GB;
3.版本:Hadoop 2.3.0,Spark 1.4,Flink 0.9
4.数据:800MB,8GB,8TB;
5.算法:K-means:以空间中K个点为中心进行聚类,对最靠近它们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
6.迭代:K=10,3组数据
测试结果:
结论:
Spark和Flink全部运行在Hadoop YARN上,性能为Flink>Spark>Hadoop(MR),迭代次数越多越明显
SparkStreaming和Filn对比
SparkStreaming | Flink | |
---|---|---|
定义 | 弹性的分布式数据集,并非真正的实时计算 | 真正的流计算,就像storm 一样; 但flink 同时支持有限的数据流计算(批处理) 和无限数据流计算(流处理) |
高容错 | 沉重 | 非常轻量级 |
内存管理 | JVM相关操作暴露给用户 | Flink 在JVM 中实现的是自己的内存管理 |
程序调优 | 只有SQL 有自动优化机制 | 自动地优化一些场景,比如避免一些昂贵的操作 (如shuffle 和sorts),还有一些中间缓存 |
1.4 发展历史
2008年,Flink 的前身已经是柏林理工大学一个研究性项目,原名 StratoSphere。
2014年,Flink被Apache孵化器所接受然后迅速地成为了 ASF(Apache Software Foundation)的顶级项目之一。
1.5 Flink在阿里的现状
基于Apache Flink在阿里巴巴搭建的平台于2016年正式上线,并从阿里巴巴的搜索和推荐这两大场景开始实现。
目前阿里巴巴所有的业务,包括阿里巴巴所有子公司都采用了基于Flink搭建的实时计算平台。
同时Flink计算平台运行在开源的Hadoop集群之上。
采用Hadoop的YARN做为资源管理调度,以 HDFS作为数据存储。
因此,Flink可以和开源大数据软件Hadoop无缝对接。
Flink架构介绍
2.1 Flink基石
Flink之所以这么流行,离不开它最重要的四个基石:
Checkpoint、State、Time、Window
-
首先是Checkpoint机制,这是Flink最重要的一个特性。Flink基于Chandy-Lamport算法实现了一个分布式的一致性的快照,从而提供了一致性的语义。Chandy-Lamport算法实际上在1985年的时候已经被提出来,但并没有被很广泛的应用,而Flink则把这个算法发扬光大了。Spark最近在实现Continue streaming,Continue streaming的目的是为了降低它处理的延时,其也需要提供这种一致性的语义,最终采用Chandy-Lamport这个算法,说明Chandy-Lamport算法在业界得到了一定的肯定。
-
提供了一致性的语义之后,Flink为了让用户在编程时能够更轻松、更容易地去管理状态,还提供了一套非常简单明了的State API,包括里面的有ValueState、ListState、MapState,近期添加了BroadcastState,使用State API能够自动享受到这种一致性的语义。
-
除此之外,Flink还实现了Watermark的机制,能够支持基于事件的时间的处理,或者说基于系统时间的处理,能够容忍数据的迟到、容忍乱序的数据。
-
另外流计算中一般在对流数据进行操作之前都会先进行开窗,即基于一个什么样的窗口上做这个计算。Flink提供了开箱即用的各种窗口,比如滑动窗口、滚动窗口、会话窗口以及非常灵活的自定义的窗口。
2.2 组件栈
Flink是一个分层架构的系统,每一层包含的组件都提供了特定的抽象,用来服务于上层组件,Flink分层的组件包含如下:
从上至下:
- 部署层:Flink支持本地运行,能独立集群或者被YARN管理的集群上运行,也能部署在云上
- 运行时:Runtime层提供了支持Flink计算的全部核心实现,为上层的API提供了基础服务
- APP:DATAStream,DataSet,Table,SQLAPI
- 扩展库:Flink还包括用于复杂事件处理,机器学习,图形处理和Apache Strom兼容性的专用代码库
2.3 Flink数据流编程模型抽象级别
Flink提供了不同的抽象级别以开发流式或者批处理应用
-
最底层提供了有状态流。它将通过 过程函数(Process Function)嵌入到 DataStream API 中。它允许用户可以自由地处理来自一个或多个流数据的事件,并使用一致、容错的状态。除此之外,用户可以注册事件时间和处理事件回调,从而使程序可以实现复杂的计算。
-
DataStream / DataSet API 是 Flink 提供的核心 API ,DataSet 处理有界的数据集,DataStream 处理有界或者无界的数据流。用户可以通过各种方法(map / flatmap / window / keyby / sum / max / min / avg / join 等)将数据进行转换 / 计算。
-
Table API 是以 表 为中心的声明式 DSL,其中表可能会动态变化(在表达流数据时)。Table API 提供了例如 select、project、join、group-by、aggregate 等操作,使用起来却更加简洁(代码量更少)。你可以在表与 DataStream/DataSet 之间无缝切换,也允许程序将 Table API 与 DataStream 以及 DataSet 混合使用。
-
Flink 提供的最高层级的抽象是 SQL 。这一层抽象在语法与表达能力上与 Table API 类似,但是是以 SQL查询表达式的形式表现程序。SQL 抽象与 Table API 交互密切,同时 SQL 查询可以直接在 Table API 定义的表上执行。
2.4 Flink程序结构
Flink程序的基本构建快是流 和转换,从概念上讲,流是(可能是永无止境)的数据记录流,而是转换是一个或者多个流作为一个或者多个流的操作,输出,并产生一个或者多个输出流
- Source:数据源,Flink在流处理和批处理上的Source
大致分为4类:基于本地的source,基于文件的source,基于网络套接字的source,自定义的source,自定义的source常见的有Apache kafka,RabbitMQ等 - Transformation:数据转换的各种操作:有Map/FlatMap/Filter/KeyBy/Reduce/Fold/Aggregations/Windows/Union/Split等,
- Sink:接收器:Flink将转换计算后的数据发送的地点,常见的Sink大概有以下几类:写入文件,打印出来,写入socket,自定义的Sink,常见的sink有Apache kafka,RabbitMQ,Mysql,ElasticSearch,Hadoop FileSystem等
2.5 Flink并行数据流
Filnk程序在执行的时候,会被映射成一个Streaming DataFlow,一个Streaming DataFlow是由一组Stream和Transformation Operator组成的,在启动一个或者多个Source Operator开始,结束于一个或者多个的Sink Operator
Flink程序本质上是并行的和分布式的,在执行过程中,一个流(stream)
包含一个或者多个流的分区,而每个operator包含一个或者多个operator子任务,操作子任务之间彼此独立,在不同的线程中执行,甚至是不同的机器或者不同的容器上,operator子任务的数量是这一特定的operator的并行度,相同程序中不同的operator有不同级别的并行度
- 一个Stream可以被分成多个Stream的分区,也就是Stream Partition。一个Operator也可以被分为多个Operator Subtask。如上图中,Source被分成Source1和Source2,它们分别为Source的Operator Subtask。每一个Operator Subtask都是在不同的线程当中独立执行的。一个Operator的并行度,就等于Operator Subtask的个数。上图Source的并行度为2。而一个Stream的并行度就等于它生成的Operator的并行度。
数据在两个operator之间传递的时候有两种模式:
-
One to One模式:两个operator用此模式传递的时候,会保持数据的分区数和数据的排序;如上图中的Source1到Map1,它就保留的Source的分区特性,以及分区元素处理的有序性。
-
Redistributing (重新分配)模式:这种模式会改变数据的分区数;每个一个operator subtask会根据选择transformation把数据发送到不同的目标subtasks,比如keyBy()会通过hashcode重新分区,broadcast()和rebalance()方法会随机重新分区;
2.6 Task和Operator chain
Flink的所有操作都称之为Operator,客户端在提交任务的时候会对Operator进行优化操作,能进行合并的Operator会被合并为一个Operator,合并后的Operator称为Operator chain,实际上就是一个执行链,每个执行链会在TaskManager上一个独立的线程中执行。
2.7 任务调度和执行
- Flink执行executor会自动根据程序代码生成DAG数据流图
- ActorSystem创建Actor将数据流图发送给JobManager中的Actor
- JobManager会不断接收TaskManager的心跳消息,从而可以获取到有效的TaskManager
- JobManager通过调度器在TaskManager中调度执行Task(在Flink中,最小的调度单元就是task,对应就是一个线程)
- 在程序运行过程中,task与task之间是可以进行数据传输的
2.8 任务槽(task-slot)和共享槽(Slot Sharing)
任务槽(task-slot)
每个TaskManager是一个JVM的进程,可以在不同的线程中执行一个或者多个子任务
为了控制一个TaskManager能接受多少个task,TaskManager通过task slot来进行控制,(一个TaskManager至少有一个task slot)
每个task slot表示TaskManger拥有的资源的一个固定大小的子集
Flink将进程的内存划分到多个slot中
图中有2个TaskManager,每个TaskManager有3个slot的,每个slot占有1/3的内存。
内存被划分到不同的slot之后可以获得如下好处:
- TaskManager最多能同时并发执行的任务是可以控制的,那就是3个,因为不能超过slot的数量。
- slot有独占的内存空间,这样在一个TaskManager中可以运行多个不同的作业,作业之间不受影响。
槽共享(Slot Sharing)
flink默认允许同一个job下的subtask可以共享slot.
这样可以使得同一个slot运行整个job的流水线(pipleline)
槽共享可以获得如下好处:
- 只需计算Job中最高并行度(parallelism)的task slot,只要这个满足,其他的job也都能满足。
- 资源分配更加公平,如果有比较空闲的slot可以将更多的任务分配给它。图中若没有任务槽共享,负载
不高的Source/Map等subtask将会占据许多资源,而负载较高的窗口subtask则会缺乏资源。 - 有了任务槽共享,可以提高分槽资源的利用率。
同时它还可以保障TaskManager给subtask的分配的slot方案更加公平。
经验上讲Slot的数量与CPU-core的数量一致为好。但考虑到超线程,可以让slotNumber=2*cpuCore.
2.9. Flink的应用场景
阿里在Flink的应用主要包含四个模块:实时监控、实时报表、流数据分析和实时仓库
实时监控:
- 用户行为预警、app crash 预警、服务器攻击预警
- 对用户行为或者相关事件进行实时监测和分析,基于风控规则进行预警
实时报表:
- 双11、双12等活动直播大屏
- 对外数据产品:生意参谋等
- 数据化运营
流数据分析:
- 实时计算相关指标反馈及时调整决策
- 内容投放、无线智能推送、实时个性化推荐等
实时仓库:
- 数据实时清洗、归并、结构化
- 数仓的补充和优化