当前位置:   article > 正文

Flink原理及架构(一)_flink核心原理

flink核心原理
  Flink核心是一个流式的数据流执行引擎,并且能够基于同一个Flink运行时,提供支持流处理和批处理两种类型应用

一.Flink介绍

  Flink核心是一个流式的数据流执行引擎,并且能够基于同一个Flink运行时,提供支持流处理和批处理两种类型应用。其针对数据流的分布式计算提供了数据分布,数据通信及容错机制等功能。基于流执行引擎,Flink提供了跟多高抽象层的API便于用户编写分布式任务。下面介绍常见的几种API;
  DataSet API: 对静态数据进行批处理作业,将静态数据抽象成分布式的数据集,用户可以方便的使用Flink提供的各种操作符对分布式数据集进行处理,支持Java,Scala和python;
  DataStream API:对数据流进行流处理作业,将流式的数据抽象成分布式的数据流,用户可以方面的对分布式数据流进行各种操作,支持Java,scala和python;
  Table API:对结构化数据进行查询操作,将结构化数据抽象成关系表,并通过SQL的DSL对关系表进行各种查询操作,支持Java和Scala;
  SQL: SQL查询是使用TableEnvironment的sqlquery()方法执行的,该方法以SQL的形式返回SQL查询的结果。Table可以在后续的SQL和Table API查询中使用,可以转换诶DataSet和DataStream,也可以写入TableSink。SQL和Table API可以无缝的整合,进行整体优化并转换为单个程序。要访问SQL中查询的表,必须在TableEnvironment中注册他,可以从TableSource,Table,DataStream和DataSet注册表,用户也可以在TableEnvironment中注册外部目录以制定数据源的位置。Blink开源后,将使Flink SQL更加完善稳定。
  StateFul Stream Processing:最低级抽象只提供有状态流,通过Process Function嵌入到DataStream API中,它允许用户自由处理来自一个或者多个流的时间,并使用一致的容错状态,此外用户可以注册event time和processing time回调,允许程序实现复杂的计算。

下面是Flink的基础架构图:
这里写图片描述
  从上图可知,Flink从另一个角度看待流处理和批处理,将2者统一起来。Flink是完全支持流处理,也就是说流处理看待数据是无界限的,批处理作为流处理的一种特殊情况,数据只是被定义为有界的。
  Flink可以与Hadoop集成,可以方便读取Hadoop项目中的组件数据,如hive,hdfs及Hbase等。以kafka作为流式的数据源,直接可以重用storm代码。

二.Flink流处理特性

1 支持高吞吐,低延迟,高性能的流处理;
2.支持带有事件事件窗口操作;
3.支持有状态计 算的exactly-once语义;
4.支持高度灵活的window操作;
5.支持具有backPressure功能的持续流模型;
6.支持具有轻量级分布式快照实现的容错;
7.一个运行时同时支持Batch on streaming和streaming处理;
8.Flink在JVM内部实现了自己的内存管理;
9.支持迭代计算;
10.支持程序自动优化:避免特定情况下Shuffer,排序等昂贵操作,中间结果又必要进行缓存;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三. 批处理与流处理统一

   在大数据领域,批处理任务和流处理任务是2中不同的任务,一个大数据系统一般被设计为只能处理其中的一个任务。如storm,spark streaming只支持流处理。而mapreduce,spark只支持批处理。 而spark streaming采用了micro-batch的架构,所以spark streaming还是基于spark批处理对流式数据进行处理。而storm,flink通过其灵活的执行引擎,且Flink能同时支持批处理任务和流处理任务。

  Flink以固定的缓存块为单位进行网络数据传输,如果缓存块的超时值为0,则Flink的数据传输方式类似于上下文提到的流式处理系统模型,此时系统可以获取低延迟的要求;如果缓存块的超时值无限大,则Flink的数据传输方式类似于上下文提到的批处理系统模型;

  总结的一点是:如果缓存块的阀值越小,那么Flink流处理系统的延迟就越低,吞吐量也越低;反之亦然;

  在统一的流式处理引擎上,Flink同时支持了流计算和批处理,并对系能(延迟,吞吐量等)有所保证,相对于其他原生的流处理和批处理刺痛,并没有因为统一执行引擎而受到影响从而大幅度减轻了用户安装,部署,监控,维护等成本。

四. Flink流处理的时间窗口

  对于流处理系统而言,流入的消息不存在上限。所以对于聚合和连接操作而言,流处理系统需要对流入的消息进行分段,然后基于每一段消息进行聚合或者连接。消息的分段即为窗口。对于大部分流处理系统而言,时间窗口一般是根据task所在节点的本地时钟进行切分,这种方式实现起来比较容易,不回产生阻塞,但可能无法满足某些场景需求:

  • 消息本身带有时间戳,用户希望按照消息本身的时间进行分段处理;
  • 由于不同节点的时钟可能不同,以及消息在流经各个节点的延迟不同,在某个节点属于同一个时间窗口处理的消息,流到下一个节对于点可能被切分到不同的时间窗口中。产生不符合预期的结果。

Flink支持3种类型的时间窗口,分别使用与用户时间窗口不同类型的要求:

  • Operrator Time:根据Task所在节点的本地时钟来切分的时间窗口;
  • Event Time:消息自带有时间戳,根据消息的时间戳进行处理,确保时间戳在同一个时间窗口的所有消息一定会被正确处理。由于消息可能乱序流入task,所以task需要缓存当前时间窗口消息处理的状态,直到确认属于该时间窗口的所有消息都被处理,才可以释放。如果乱序的消息延迟很高会影响到分布式系统的吞吐两盒延迟;
  • Ingress Time:有时时间并不带有时间戳,但用户依然希望按照消息而不是节点时钟划分时间窗口;例如避免上面提到的第二个问题,此时可以在消息源流入Flink流处理系统时自动生成增量的时间戳赋予消息,之后处理的流程与Event Time相同,Ingress Time可以看做是Event Time的一个特例,由于在消息源时间戳一定是有序的,所以在流处理系统中,相对于Event Time,其乱序的消息延迟不回很高,因此对于Flink分布式系统的吞吐量很延迟的影响也会更小;

五.Event Time时间窗口的实现

  Flink借鉴了Google的MillWheel项目,通过WaterMark来支持基于Event Time的时间窗口。当操作符通过基于Event Time的时间窗口来处理数据时,它必须在确定所有属于该时间窗口的消息全部流入此操作符后才能开始数据处理。但是由于消息可能是乱序的,所以操作符无法直接确认何时所有属于该时间窗口的消息全部流入此操作符。WaterMark包含一个时间戳,Flink使用WaterMark标记所有小于该时间戳的消息都已流入,Flink的数据源在确认所有小于某个时间戳的消息都已输出到Flink流处理系统后,会生成一个包含该时间戳的WaterMark,插入到消息流中输出到Flink流处理系统中,Flink操作符按照时间窗口缓存所有流入的消息,当操作符处理到WaterMark时,它对所有小于该WaterMark时间戳的时间窗口数据进行处理并发送到下一个操作符节点,然后也将WaterMark发送到下一个操作符节点。

  为了保证能够处理所有属于某个时间窗口的消息,操作符必须等到大于这个时间窗口的WaterMark之后才能开始对该时间窗口的消息进行处理,相对于基于Operator Time的时间窗口,Flink需要占用更多内存,且会直接影响消息处理的延迟时间。对此,一个可能的优化措施是,对于聚合类的操作符,可以提前对部分消息进行聚合操作,当有属于该时间窗口的新消息流入时,基于之前的部分聚合结果继续计算,这样的话,只需缓存中间计算结果即可,无需缓存该时间窗口的所有消息。

  对于基于Event Time时间窗口的操作符来说,流入WaterMark的时间戳与当前节点的时钟一致是最简单理想的状况,但是在实际环境中是不可能的,由于消息的乱序以及前面节点处理效率的不同,总是会有某些消息流入时间大于其本身的时间戳.

基于时间戳的排序:

  在流处理系统中,由于流入的消息是无限的,所以对消息进行排序基本上被认为是不可行的。但是在Flink流处理系统中,基于WaterMark,Flink实现了基于时间戳的全局排序。排序的实现思路如下:排序操作符缓存所有流入的消息,当其接收到WaterMark时,对时间戳小于该WaterMark的消息进行排序,并发送到下一个节点,在此排序操作符中释放所有时间戳小于该WaterMark的消息,继续缓存流入的消息,等待下一个WaterMark触发下一次排序。

  由于WaterMark保证了在其之后不会出现时间戳比它小的消息,所以可以保证排序的正确性。需要注意的是,如果排序操作符有多个节点,只能保证每个节点的流出消息是有序的,节点之间的消息不能保证有序,要实现全局有序,则只能有一个排序操作符节点。通过支持基于Event Time的消息处理,Flink扩展了其流处理系统的应用范围,使得更多的流处理任务可以通过Flink来执行。

最后说明一下:
  由于容错机制和内存管理内容较多,在在后续章节中会贴出详细的图示方便读者们更好的理解Flink相关内容,此文章由于各种原因暂时没有很好的呈现给大家,请多谅解!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/891318
推荐阅读
相关标签
  

闽ICP备14008679号