flink特性总结:

flink是第三代分布式流处理器,它功能丰富而强大。

flink的核心特性:

flink区别与传统处理框架的特性如下:

高吞吐和低延迟,每秒处理数百万个事件,毫秒级延迟。

结果的准确性,flink提供了事件时间(event-time)和处理时间(processing-time)语义,对于乱序事件流,事件时间语义仍然能提供一致且准确的结果。

精确一次的状态一致性保证。

可以连接最常用的存储系统,如kafka,cassandra,elasticsearch,jdbc,kinesis和文件系统,如hdfs 和 s3 .

高可用,本身高用的设置,加上k8s,yarn和mesos的紧密集成,再加上从故障中快速恢复和动态扩展任力的能力。flink能做到极少的停机时间7*24 小时全天候运行。

能够更新应用程序并将作业jobs迁移到不同的flink集群,而不会丢失应用程序的状态。

分层api:

除了上述的特性之外,flink还是一个非常易于开发的框架,因为它拥有易于使用的分层api,整体的api分层如下:

底层apis--> 核心apis--> 声明式领域专用语言-->最高层语言

最底层级的抽象仅仅提供了有状态流,它将处理函数嵌入到了datastream api中,底层处理函数(process function)与datastream api相集成,可以对操作进行抽象,它允许用户可以自定义状态处理来自一个或多个数据流的事件。且状态具有一致性和容错保证。除此之外,用户可以注册事件时间并处理时间回调,从而使用程序可以处理复杂的计算。

实际上,大多数应用并不需要上述的底层抽象,而是直接针对核心api(core apis)进程编程,比如datastream api用于处理有界或无界流数据以及dataset api用于处理有界数据集。这些api为数据处理提供了通用的构建模块。比如由用户定义的多种形式的转换(transformation),连接(joins),聚合(aggregations)、窗口(windows)操作等。dataset api为有界数据集提供了额外的支持,例如循环和迭代。这些api处理的数据类型以类(classes)的形式由各自的编程语方所表示。

table api是以表为中心的声明式编程,其中表在表达流数据时会动态变化。table api遵循关系模型。表有二维数据结构(schema)类似于关系数据库中的表,同时api提供可比较的操作。 select ,join,group-by,aggregate等。

尽管table api可以通过多种类型的用户自定义udf 进行扩展,仍不如信心api更具有表达能力,但是使用起来代码量更少,更加简洁,除此之外,table api程序在执行之前会使用内置优化器进行优化。

我们可以在表和Datastream/dataset之间无缝切换,以允许将table api与datastream 以及dataset 混合使用。

flink提供的更高层的抽象是sql,这一层抽象在语法与表达能力上与table api类似,但是是以Sql 查询表达式的形式表现程序,sql抽象与table api交互密切。同时Sql查询可以直接在table api定义的表上执行。

目前flink 提供最高级的抽象sql ,这一层抽象在语法与表达能力上与table api类似,但是以Sql查询表达式的形式表现程序,sql抽象与table api交互密切,同时sql查询可以直接在table api定义的表上执行。

目前flink sql和table api还在开发完善的过程中。

flink vs spark 

而flink则认为:流处理才是最基本的操作,批处理也可以统一流处理,而flink的世界观中,万物皆流,实时数据是标准的,没有界限的流,则离线数据则是有界限的流,如图1-13 所示,就是所谓的无界流和有界流。

1、无界数据流

所谓无界数据流,就是有头没尾,数据的生成和传递会开始和永远不会结束。我们无法等待所有数据都到达,因为输入是无界的,永无止境,数据没有都到达的时候,所以对于无界数据流,必须连续处理,也就是说必须在获取数据后立即处理。在处理无界流时,为了保证结果的正确性。我们必须能够做到按照顺序处理数据。

2、有界数据流

对应的,有界数据有明确定义的开始和结束,所以我们可以通过获取所有数据来处理有界流,处理有界流就不需要严格保证数据的顺序,因为总可以对有界数据集进行排序,有界流的处理也就是批处理。

数据模型和运行架构

除了三观不合,spark和flink在底层实现最主要的差别就在于数据模型不同。

flink的基本数据模型是dataflow以及事件event序列。flink基本上是完全按照google的dataflow模型实现,所以从底层数据模型上看,flink是以处理流处理数据作为设计目录。更加适合流处理的场景。

数据模型不同,对应在运行处理的流程上,自然也会不同的架构。spark做批计算,需要将任务对应的dag划分阶段stage,一个完成后经过shuffle再进行下一阶段的计算。而flink是标准的执行模式,一个事件在一个节点处理完后可以直接发往下一节点的处理。

spark 2.0之后新的strucated streaming流处理引擎借鉴dataflow进行大量的优化,同样做到了低延迟,时间正确性以及精确一次性语义保证,spark 2.3 以后引入的连续处理,。更是可以在至少一次语义保证下做到1毫秒的延迟,而flink 1.9 版本合并blink以来。在Sql的表达和批处正是的能力同样有了长足的进步。

Flink中几个关键组件:客户端(Client),作业管理器(JobManager)和任务管理器(taskManager).我们代码,实际上是由客户获取并做转换,之后提交给jobmanager的,所以jobmanager就是flink集群的管事人,对作业进行中央调度管理。而它获取到要执行的作业后,会进行一步处理转换,然后分发任务给众多的taskmanager,这里的taskmanager,就是直正干活的人,数据的处理操作都是它们来做的。

另外,flink-conf.yaml文件中还可以对集群中的jobmanager和taskmanager组件进行优化配置,主要配置如下:

jobmanager.memory.process.size 对jobmanger 进行可使用到的全部内存进行配置。包括 jvm元空间和其他开销,默认为1600M,可以根据集群规模进行适当的调整。

taskmanger.memory.process.size对taskmanger 进程可使用到的全部内存进行配置。包括jvm元空间和其他开销。默认为1600M,可以根据集群规模进行适当调整。

taskmanger.numerberoftaskslots,对于每个taskmanager能够分配置的slot数量进行配置,默认为1,可根据taskmanager所在的机器能够提供给flink的cpu的数量决定,所谓slot就是taskmanger中具体运行一个任务所分配的计算资源。

parallelism.default:flink任务执行的默认并行度,优先级低于代码中进行并行度配置和任务提交时使用参数指定的并行度数量。


yarn集群:接下来我们再看一下资源管理平台,具体的提交流程。我们以yarn 为例。分不同的部署模式来具体说明。

会话模式

在会话模式:我们需要先启动一个yarn session,这个会话创建一个flink集群。

这里只启动了jobmanager,而taskmanager可以要根据需要动态启动。在jobmanger内部,由于还没有提交作业。所以resoucemanager和dispatcher在运行。

客户端通过rest接口,将作业提交给分发器。

分发器启动jobmaater,将将作业(jobgraph)提交给jobmaster

jobmaster向资源管理器请求资源(slots)

资源管理器通知taskmanager为新的作业提供slots

taskmanager连接到对应的jobmaster,提供slots

jobaster交需要执行的任务分发taskmanager执行任务。

可见,整个流程除了请求资源时要上报yarn 资源管理器,其他与 抽象的流程几乎完全一样。

(第四章,还需要再看一下)

datastream api基础篇