Flink初识
Flink同时支持 高吞吐、低延迟和exactly-once语义的实时计算能力,同时提供了基于流式计算引擎处理批量数据的计算能力,真正意义上实现了批流统一。
使用Hadoop MapReduce进行批量数据的处理,使用Apache Storm进行实时数据的处理。这种架构在一定程度上解决了不同计算类型的问题,但是带来的问题是框架太多导致平台复杂度过高、运维成本高等问题。
Spark本身是基于批处理模式,不能完美高效处理原生的数据流。
Flink的优势
- 同时支持高吞吐、低延迟、高性能
- 支持事件时间概念,Flink支持基于事件时间语义进行窗口计算,也就是使用事件本身产生的时间。这种机制使得即使事件乱序到达,流系统也能够计算出精确的结果,保持了事件原本产生时的时序性
- 支持有状态计算,在流计算过程中将算子的中间结果数据保存在内存或文件系统中,等下一个事件进入算子后可以从之前的状态中获取中间结果计算当前的结果
- 支持高度灵活的窗口操作
- 基于轻量级分布式快照实现的容错
- 基于JVM实现独立的内存管理,通过序列化/反序列化方法将所有数据对象转换成二进制在内存中存储
- Save Points
Flink基本架构
分层的架构设计理念,降低系统耦合度,也为上层用户提供了丰富的接口。共有三层,由下往下依次是API&Libraries层、Runtime核心层以及物理部署层。
基本组件栈
API&Libraries层
组件有基于流处理的CEP(复杂事件处理库)、SQL& Table库和基于批处理的FlinkML(机器学习库)、GElly(图处理库)。API层包括构建流计算应用的DataStream API和批计算应用的DataSet API。
Runtime核心层
该层主要负责对上层不同接口提供服务,支持分布式Stream作业的执行、JobGraph到ExecutionGraph的映射转换、任务调度等。将DataStream和DataSet转换成统一可执行的Task Operator,达到在流式引擎下同时处理批量计算和流式计算的目的。
物理部署层
该层主要涉及Flink的部署模式,目前Flink支持多种部署模式:本地、Standalone/YARN、Kubernetes。
基本架构图
Flink整个系统主要由两个组件组成,JobManager和TaskManager。其中JobManager作为Master节点,TaskManager为Worker节点,也是主从结构。所有通信都是借助Akka Framework。
- 客户端,将任务提交到集群。与JobManager建立连接,提交任务,获取任务执行状态。
- JobManager负责集群任务的调度以及资源的管理。根据TaskManager上TaskSlot的使用情况,为提交的应用分配相应的TaskSlots资源。
- TaskManager相当于整个集群的Slave节点,负责具体任务执行和对应任务在每个节点的资源申请与管理。
编程模型
数据集类型
根据现实的数据产生方式和数据产生是否含有边界(具有起始点和终止点)角度,将数据分为两种类型的数据集,一种是有界数据集,另外一种是无界数据集。
有界数据集
有界数据集具有时间边界,在处理过程中数据一定会在某个时间范围内起始和结束。对有界数据集的处理称为批计算。
无界数据集
数据从开始生产就一直持续不断地产生新的数据,例如服务器的日志、传感器信号数据等。对无界数据集的数据处理方式被称为流式数据处理,流处理。
编程接口
根据数据集类型的不同将数据处理接口分为两大类,一类是支持批计算的接口DataSet API,另外一类是支持流计算的接口DataStream API。同时Flink将数据处理接口抽象成四层,由上向下分别为SQL API、Table API、DataStream /DataSet API及Statefule Stream Processing API。
- Flink SQL,SQL语言具有比较低的学习成本,能够让数据分析人员和开发人员更快
- Table API,将内存中DataStream和DataSet数据集在原有的基础之上增加了Schema信息,将数据类型统一抽象成表结构。可以和DataStream和DataSet之间进行互相转换,提供GroupByKey,Join等操作。
- DataStream和DataSet主要面向具有开发经验的用户,用户可以使用DataStream API处理无界流数据,使用DataSet API处理批量数据。提供map,filter,aggregations,window等方法。
- Stateful Stream Process API,最底层的接口,可以使用其来操作状态、时间等底层数据。
程序结构
- Execution Envirionment,第一步是获取相应的执行环境,决定了程序运行在本地环境或者是集群环境。批处理作业和流处理作业分别使用不同的Execution Environment。StreamExecution ENvironment用来做流式数据处理环境,ExecutionEnvironment是批数据处理环境。
- 初始化数据,将外部数据转换成DataStream
或DataSet 数据集。通过调用readTextFile()方法。 - 执行转换操作,Flink中的Transformation操作是通过不同的Operator实现,每个Operator内部通过实现Function接口完成数据处理逻辑的定义。用户只需要定义每种算子执行的函数逻辑,然后应用在数据转换操作Operator接口中即可。
- 分区Key指定,某些算子需要根据指定的key进行转换,join、coGroup、groupBy类算子,需要先将数据转换成对应的KeyedStream和GroupedDataSet,将相同key值的数据路由到相同的Pipeline中,然后进行下一步的计算操作。
- 输出结果,DataStream和DataSet定义了基本的数据输出方法,如文件输出writeAsText()。
- 程序触发,需要调用env的execute()方法来触发应用程序的执行。