天天看点

Flink学习小计-编程模型

flink的编程抽象级别

并行计算模型

算子并行度

环境并行度

系统层面并行度

slot并行度

flink提供了不同的编程抽象级别,允许我们以合适的方式去开发相应的流式/批处理应用。

Flink学习小计-编程模型

有状态的流式处理级别,flink提供的最低抽象级别,保证了数据流是有状态的,通过处理函数嵌入到了datastream api中,通常不会直接使用 。

核心api:比较常用到,flink内建的这些流式的api可以构建复杂的业务逻辑,支持图结构的分布式计算流,区别于mapreduce这种只支持map和reduce编程范式的计算引擎(众所周知,mapreduce只支持map和reduce编程范式)。

核心api又包含了两大类,一类是支持批处理的dataset api,另一类是支持流处理的datastream api,从中可以看出flink不同于其他的大数据项目(只支持一种任务,批处理或者流处理),其被设计的天然同时支持批处理任务以及流处理任务;去除这两个极端的的设计,简单理解关键点还是在于flink执行引擎允许用户自定义设置缓存块的大小(超时值)。假设缓存块的超时值足够小,那么整个计算过程的延迟就足够低,必然的是系统的吞吐量会下降;反之,延迟高,吞吐量大,我们可以根据具体的业务场景去配置适合的数值,从而折中延迟和系统吞吐。总的来说,flink给了我们足够的自由度~

table api & sql :table api 是以表为中心的声明式dsl(领域特定语言),当这些table表示的是stream时,table是动态变化的,动态变化体现在数据流会不断提供新的数据。table api遵循扩展的关系模型,提供了包括select、project、join、group-by、aggregate等操作;table api等效于最高级别的标准sql,对于流式分析,sql可以让更多的人在更短的时间内在数据流上开发应用程序,且 sql可以得到有效优化、高效的评估。

实际上,无论用table api去构建逻辑,还是sql去声明想要的结果,最终都会被翻译成相同的逻辑表示,并由apache calcite进行优化,并编译到datastream或dataset程序中;实际上table api和sql除了语法不同以外,其他的方面没有什么不同的地方,甚至于优化和编译过程都不关心具体使用的是哪种语法。

flink中可以通过编程的方式显示的声明每个算子的并行度,如下图:

Flink学习小计-编程模型

上诉声明的含义是,source的并行度为2,map的并行度为2,keyby&windows&sum的并行度为2,sink的并行度为1。为了最大限度的利用资源,flink会将每个算子的各个并行度实例进行了链式操作,链式操作结束之后得到task,再作为一个调度执行单元,放到一个slot(线程)里执行。可以结合官方给出的图例进行理解:

Flink学习小计-编程模型

可以看出flink使用两个slot去完成本次任务,下标1的为一组,下标2的为一组。即sink任务的并行度为1,其他任务的并行度均为2。

且流中的数据在不同operator之间的传递方式有两种:

one-to-one:上图的source[1] -> map[1]。

redistributing:上图的map[1] -> keyby()/window()/apply() [1]和[2]。

如果要将一个flink程序的全部任务(算子)设置为一样的并行度,那么可以考虑将任务的并行度提升到执行环境的层面;当然,我们还可以具体指定某个任务的并行度,从而覆盖掉执行环境的并行度。设置环境并行度的方式(java客户端)如图:

Flink学习小计-编程模型

系统层面的并行度是对执行环境并行度的统一约束,对所有执行环境生效,且可以被覆盖;可以通过parallelism.default,属性在conf/flink-conf.yaml文件中设置。

Flink学习小计-编程模型

slot并行度其实和任务没有直接的联系,它反映的是taskmanager的资源分配情况,合理的给出taskmanager中slot数量,会提升整体性能,以及更合理的利用计算资源。一般来讲,slot数量最合适的是跟taskmanager的cpu核心数量成正比。

Flink学习小计-编程模型

end~

[1]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference

继续阅读