Flink

Flink

  • Flink 是为分布式、高性能、随时可用以及准确的流处理应用框架,用于对无界和有界数据流进行有状态计算,并且以内存执行速度和任意规模来执行计算,在保证'exactly-once'的同时具有低延迟、高吞吐的处理能力。
  1. 基于事件驱动:是有状态的事件驱动,从一个或多个事件流提取数据,并根据事件的到来触发计算、状态更新或其他外部操作等。如Kafka的消息队列几乎都是事件驱动。

  2. 流批处理:

    • ·批数据是有界、持久、大量的适合需要访问全部数据才能完成计算的工作,通常用于离线处理。
      • 有界流数据:有明确定义的开始和结束,在执行操作之前可以获取所有数据来处理有界流,并且处理有界流不需要有序获取,可以随时对有界数据集进行排序。
    • 流数据无界、实时的,无需针对整个数据集进行操作,而是对通过系统的每个数据项进行操作,通常用于处理实时数据。
      • 无界流数据:有开始但没有结束,不会在生成时终止并提供数据,需要实时的对无界流的数据进行处理,在任何时间点都不会完成,通常要求数据以特地的顺序获取,以便能够推断结果的完整性。

    说明:

    事件驱动:事件驱动不需要外部的数据库,用状态来保存中间的计算过程和结果。
    关系驱动:传统的关系驱动需要借助于外部存储进行读写,通常为关系型数据库。

Flink与Spark的区别:

  1. 计算模型不同:
    • SparkStreaming 微批次处理模型,基于时间触发,高延迟。
    • Flink 标准的流式处理,基于事件触发的,低延迟、高吞吐。
  2. 架构模型不同:
    • SparkStreaming 任务处理依赖于Driver、Executor(Yarn模式) 或Master、Worker(Standalone模式)。
    • Flink 任务的处理依赖于JobManager、TaskManager、Slot。
  3. 任务调度不同:
    • SparkStreaming 会构建DAG,并且维护了一个 'DStream Graph',经过ReceiverTracker、JobGenerate、JobScheduler。
    • Flink StreamGraph->JobGraph->ExecutionGraph->PhysicalGraph
  4. 时间机制不同:
    • SparkStreaming 支持处理时间。
    • Flink 支持处理时间、事件时间、注入时间,更好的实现精准一次性消费,支持watermark处理滞后数据。
  5. 容错机制不同:
    • SparkStreaming 支持persist对RDD进行缓存,还可以设置checkpoint用于故障恢,但只能解决数据不丢失不能解决数据重复问题。
    • Flink 支持两阶段提交Checkpoint,保证精准一次。
  6. 窗口机制不同:
    • SparkStreaming 的窗口先将多个批次的数据准备好,然后将多个RDD进行union汇总,并且窗口大小必须是批次大小的整数倍,否则窗口会将某个批次的数据且分开,会破坏数据的完整性。
    • Flink:Flink的窗口是先将每个窗口准备好,等到数据流的到来,每来一条数据处理一次,对窗口大小没有特定需求。
  7. CEP的支持:Flink内置CEP,而Spark没有内置CEP。
  • Stateful Stream Processing、DataStream/DataSet API、TableAPI、SQL。

    最底层级的抽象仅仅提供了有状态流,它将通过过程函数被嵌入到DataStream API中。

  • Flik流批一体:
    Flink内部有两套不同数据处理方式的API,DataStream和DataSet。
    DataSource底层是一个operator算子,该算子底层是DataSet。
    DataStreamSource底层是DataStream。

    说明:

    Flink1.12 版本的流批一体存在一些BUG,批处理API处理数据输出结果时经过reduce后的结果如果只有一个数据不会进入reduce,并且批处理不会保存状态。

  1. LocalCluster模式> 本地集群模式,通常用于测试和学习,是默认模式。

  2. Standalone模式> 独立集群模式,支持Web UI界面提交Flink应用。

    Standalone模式高可用:解决单点故障问题,主备 JobManager 实例之间没有明显的区别,同时启动多个Jobmanager, 其中一个为leader其他为standby,当leader挂了,其他的才会有一个成为leader。

    **说明: **

    1.default、Standlone模式下通过 'flink run -m hostname:8081 -c '提交任务。

    2.Standalone高可用模式下,需要启动zk、Hdfs并且flink中没有hadoop的jar包,需要在环境变量中添加flink所需的hdoop环境变量。

  3. Yarn模式> 独立部署模式,会动态的分配TaskManager资源,不需要启动flink集群,Yarn会根据任务自动的启动master和workers,有任务时分配资源,没有任务时不占用资源,且Flink Yarn模式是Flink的一个客户端不需要分发。

    说明:Yarn模式由Flink自身提供计算资源,无需其他框架提供资源,但是Flink主要用来计算,自身提供的资源调度并不如外部集成好,所以采用集成外部Yarn。

    • Session-Cluster:会先在Yarn启动一个Flink集群,向Yarn申请资源,多个任务共享这个集群的资源,存在资源争抢,并且任务会相互影响。

      缺点: 如果提交的作业中有长时间执行的大作业,占用了该Flink集群的所有资源,则后续无法提交新的job,所以该模式适合需要频繁提交的多个小Job,且执行时间都不长。

      说明: Session-Cluster模式下先通过 'bin/yarn-session.sh -d ' 后台启动一个Flink集群,然后再通过 'bin/flink run -c'提交任务, 在session-Cluster模式和standalone模式都存在时,由于会先去寻找session-Cluster环境,如果想跳过session-Cluster模式,使用standalone模式的话可以通过 -m 指定Jobmanager(地址:web端口),会直接使用standalone模式的flink。

    • Per-Job-Cluster:每个任务都会在yarn上单独启动一个集群,任务的执行互不干扰。推荐使用perjob和application模式。

      说明: Per-Job-Cluster 模式下,通过 ' bin/flink run -t yarn-per-job -c ' 提交任务,如果有多个session集群时,手动指定yarn-Session集群 ' bin/flink run -t yarn-session -Dyarn.application.id=application_XXXX_YY '

    • Application Mod:与Perjob模式类似,区别在于代码的主方法在集群执行,而Perjob的mian方法在用户提交代码的客户端执行。

      说明: Application Mode模式下,通过 ' bin/flink run-application -t yarn-application -c ' 提交任务。

    • Yarn高可用:只有一个Master,但是提供了重试机制。在flinkyarn的配置文件中不用配集群id,Yarn模式默认将Applicationid作为集群id,如果配置了会导致所有的集群id都是同一个会导致冲突。

  1. Client:用于将DataStream发送的JobManager,可以与Jobmanager保持连接也可以断开连接。

  2. JobManager:作为Master,控制程序执行的主进程,类似大哥,用于接收JobGraph、LogicalDataflowGraph、其他资源JAR包,然后将JobGraph转换成一个物理层面的数据流图ExecutionGraph,它包含了所有可以并发执行的任务。JobManager需要向内置的RM申请资源。

    • JobManager内置的三组件:

      ResourceManager>:是Flink内置的资源调度器,整个集群只有一个。主要负责管理任务管理器的Slot资源。

      说明:当JobManager申请插槽资源时,ResourceManager会将有空闲插槽的TaskManager分配给JobManager,如果资源不够,会向资源提供平台发起会话,用来提供启动TaskManager的容器。并且ResourceManager还负责终止空闲的TaskManager释放计算资源。

      Dispatcher>: 分发器,负责接收用户提供的作业,并且负责为这个新提交的作业启动一个新的JobManager组件。

      说明:Dispatcher会启动一个WebUI用来监控任务的执行情况,Dispatcher并非必须的。

      JobMaster>:负责管理单个JobGraph的执行,多个Job可以同时运行在一个Flink集群中,每个Job都有自己的JobMaster。

  3. TaskManager: 是Flink的工作进程,类似小弟可以有多个,每个TaskManager都有一定数量的Slot,TaskManager启动后会向ResourceManager注册自己的插槽,收到任务后TaskManager会将自己的插槽提供给JobManager调用。

    说明:任务执行的过程中,TaskManager可以跟其它运行相同应用程序的TaskManager交换数据。

关于并行度:

  • 并行度:每一个算子在运行中的子任务(Subtask)的数量称为并行度,所有算子并行度的默认值为1。

  • SubTask: 每一个算子的一个并行实例,即代表一个并行度。

  • Task: 每一个算子的一个子任务,或多个算子的子任务满足某种不可描述的关系('one-to-one'、并行度相同,经过OperatorChain优化)串在一起之后的子任务。

  • 并行度优先级: 代码的算子指定 > 代码的env(全局指定) > 提交参数 > 配置文件默认

    说明:对于多并行度执行时的问题,相同交易码的数据可能进入到不同的分区,导致相同的交易码匹配不上。

  • Operator Chains:相同并行度的'one-to-one'操作,Flink将这样相连的算子链接在一起形成一个task,原来的算子成为里面的一部分。

    说明:算子链化成Task能减少线程之间的切换和基于缓存区的数据交换,在减少网络IO时延和序列化与反序列化延时的同时提升吞吐量。

Slot:

  • Slot是每个TaskManager上的资源单位,每个TaskManager都至少有一个Slot。

  • 每个Job所需的Slot数量:由该任务的所有共享组中最大算子的并行度之和。

    说明:每个算子都可以单独的设置共享组,通过共享组来增大资源(Slot)的利用率,同时会增大IO,为了尽可能的避免网络IO,设置共享组之后的算子同属于相同的共享组,用来减小网络IO。

TaskManager与Slots的关系:

  • 每个TaskManager都是一个JVM进程,它可能会在独立的线程上执行一个Task。而Slot用来控制一个TaskManager可以接收多少个task,每个TaskManager至少都有一个Task SLot。
  • Spark Core 是Job内部共享的,如果某个Job的core是空闲的,只能给自己用并不能给其他的Job使用。而Flink的slot是job之间共享的, 不同任务之间可以共享资源。

并行度与slot的关系:

  1. 同一个算子的子任务(一个并行度),不能在同一个slot里,即一个算子的一个并行度会占用一个插槽。
  2. 不同算子的子任务,可以共享一个slot。
  3. Slot数量 '<' 算子最大并行度:
    如果是 Standalone模式,那么会卡住,且占用当前已有资源,等待资源足够时再执行。
    如果是 Yarn模式,会动态申请更多资源。
    并行度是指一个算子可以同时并行执行的任务数,而slot指TaskManager上用来跑任务的资源。
    整个流式程序的并行度 = 所有共享组中算子的最大并行度之和 。
  1. Flink分区:分区是物理逻辑上的划分,算子的一个并行实例对应一个分区。
  2. Flink分组:分组是逻辑上的划分,按照指定的Key区分不同的组。
    说明:
    1.同一分组一定在同一分区,且同一分区可以有多个分组。
    2.Spark如果要改变它的并行度需要经过shuffle改变它的分区数,Spark一个分组的数据会对应到一个分区中,分区数等于组数。
  • 执行图流程:共四层 StreamGraph -> JobGraph -> ExecutionGraph -> Physical Graph。
  1. StreamGraph:StreamAPI代码形成的原始图,用来表示程序的拓扑结构。
  2. JobGraph:StreamGraph经过链化操作形成JobGraph,然后通过客户端发送给JobManager。
  3. ExecutionGraph:JobManager 根据 JobGraph 生成ExecutionGraph,是JobGraph的并行化版本,是调度层最核心的数据结构。
  4. PhysicalGraph:JobManager根据ExecutionGraph对Job进行调度后,在TaskManager上部署Task后形成的图,并不是具体的数据结构。

任务提交流程:

  • 通用> : App提交应用给JobManager,JobManager中的Dispatcher负责接收数据,Dispatcher收到数据启动JobMaster,JobMaster启动后会向JobManager内部的ResouceManager申请资源,ResourceManager收到请求后启动Taskmanager,TaskManager启动后会向ResourceManager注册当前节点的空闲插槽数,之后ResourceManager向TaskManager通知JobManager运行任务所需的插槽数,然后TaskManager向JobManaager提供插槽,最后JobManager向TaskManager提交要运行的任务。
  • Yarn> :

Flink开发的流式处理:首先要有 Environment,然后通过 Source 将数据读入, 然后通过 Transform 算子对数据进行一系列的操作,最后通过 Sink 将数据写出。
说明:Source是env调用的,Sink是流调用的。

posted @ 2021-06-01 15:34  yuexiuping  阅读(240)  评论(0编辑  收藏  举报