Flink

  1. Flink 主要特点

    1. 事件驱动
    2. 基于流的世界观:在 Flink 的世界观中,一切都是由流组成的,离线数据是有界的流;实时数据是一个没有界限的流
    3. 分层API:越顶层越抽象,表达含义越简明,使用越方便;越底层越具体,表达能力越丰富,使用越灵活
    4. 支持事件时间(event-time)和处理时间(processing-time)语义
    5. 精确一次(exactly-once)的状态一致性保证
    6. 低延迟,每秒处理数百万个时间,毫秒级延迟
    7. 与众多常用存储系统的连接
    8. 高可用,动态扩展,实现 7*24 小时全天候运行
  2. Flink 和 Spark Streaming 比较

    1. 流(stream)和微批(micro-batching)

    2. 数据模型

      1. spark 采用 RDD 模型
      2. flink 基本数据模型是数据流,以及事件序列
    3. 运行时架构

      1. spark 时批计算,将 DAG 划分不同的 stage,一个完成后才能下一个
      2. flink 是标准的流执行模式,一个事件在一个节点处理完后可以直接发往下一节点进行处理
  3. Flink Standalone部署

    在lib下增加hadoop依赖 flink-shaded-hadoop-2-uber-2.8.3-10.0.jar,并复制三份

    vi ./conf/flink-conf.yaml # taskmanager.numberOfTaskSlots: 4
    vi ./conf/slaves # hadoop03 hadoop04
    ./bin/start-cluster.sh
    ./bin/stop-cluster.sh
    ./bin/flink run -c com.csmar.flink.flinktutorial.wc.StreamWordCount -p 3 /xxx/xxx/xxx/bigdata-1.0-SNAPSHOT.jar --host 192.168.10.128 --port 7777
    ./bin/flink_list # 查看job的 jobId
    ./bin/flink cancel xxxxxxx
    
  4. Flink Yarn部署

    1. Session Cluster
    # -n : container,TaskManager的数量
    # -s :每个 TaskManager的 slot 数量,默认一个 slot 一个 core,默认每个 taskmanager 的 slot 的个数是 1,有时候会多一些 taskmanager 做冗余
    # -jm:JobManager 的内存 MB
    # -tm:taskmanager 的内存 MB
    # -nm:yarn 的appName
    # -d:后台执行
    
    ./yarn-session.sh -n 2 -s 2 -jm 1024 -tm 1024 -nm test -d
    ./flink run -c com.csmar.flink.flinktutorial.wc.StreamWordCount bigdata-1.0-SNAPSHOT.jar --host 192.168.10.128 --port 7777
    yarn application kill application_xxxxxxx
    
    1. Per Job Cluster

      # 启动 hadoop 集群
      # 不启动 yarn-session,直接执行 job
      ./flink run -m yarn-cluster -c com.csmar.flink.flinktutorial.wc.StreamWordCount bigdata-1.0-SNAPSHOT.jar --host 192.168.10.128 --port 7777
      yarn application kill application_xxxxxxx
      
    2. Kubernates 部署

  5. Flink 运行时架构

    1. Flink 运行时组件

      JobManager:控制应用程序执行的主进程,每个应用程序都会被一个不同的 JobManager 所控制执行

      TaskManager:任务管理器。通常在Flink中会有多个TaskManager运行,每一个TaskManager都包含了一定数量的插槽(slots)。插槽的数量限制了 TaskManager 能够并行执行的速度。

      ResourceManager:资源管理器,主要负责管理插槽

      Dispacher:分发器,为应用提供 REST 接口

    2. 任务提交流程

    3. Yarn上作业提交流程

    4. 作业调度原理及思考问题

    5. slot 和任务调度

      1. 并行度:一个特定算子的子任务的个数被称为并行度。一般情况下,一个stream的并行度,可以认为就是其所有算子中最大的并行度
      2. TaskManager 和 Slots
        1. Flink 中每一个 Task Manager 都是一个 JVM 进程,它可能会在独立的线程上执行一个或多个子任务
        2. 为了控制一个 TaskManager 能接受多少个task,TaskManager 通过 task slot 来进行控制
    6. 程序与数据流

      所有的 Flink 程序都是由三部分组成:Source 负责读取数据源、Transformation 利用各种算子进行处理加工、Sink 负责输出

    7. 任务链

      1. Flink 采用了一种称为任务链的优化技术,可以在特定条件下减少本地通信的开销。为了满足任务链的要求,必须将两个或多个算子设为相同的并行度,并通过本地转发的方式进行连接
      2. 相同并行度的one-to-one操作,Flink这样相连的算子链接在一起形成一个 task,原来的算子称为里面的 subtask
      3. 并行度相同、并且是 one-to-one 操作,两个条件缺一不可
  6. Flink 流处理 API

    kafka 进 kafka 出,可以做数据清洗

  7. 窗口(window)

    窗口就是将无限流切割为有限流的一种方式,它会将流数据分发到有限大小的桶(bucket)中进行分析。

    window类型(Time Window)

    ​ 时间窗口

    ​ 计数窗口

    滚动窗口 Tumbling Window:固定窗口长度切分 + 时间对齐,窗口长度固定,没有重叠

    滑动窗口 Sliding Window:滑动窗口由固定的窗口长度和滑动间隔组成 +窗口长度固定,可以有重叠

    会话窗口 Session Window:由一系列事件组合一个指定长度的timeout间隙组成,也就是一段时间没有接收到新数据就会生成新的窗口 + 时间无对齐

​ 窗口分配器(window assigner)

​ window方法接收的输入参数是一个 WindowAssigner,WindowAssigner 负责将每条输入的数据分发到正确的window中。

​ 滚动窗口 tumbling window

​ 滚动窗口 sliding window

​ 会话窗口 session window

​ 全局窗口 global window

​ 窗口函数(window function)

​ 增量聚合函数:每条数据到来就进行计算,保持一个简单的状态

​ 全窗口函数:先把窗口所有数据收集起来,等到计算的时候会遍历所有数据

​ 其他可选API

​ trigger() ——触发器

​ evictor()——移除器:定义移除某些数据的逻辑

​ allowedLateness()——9点输出结果,后面继续等数据,来一个处理一个,时间到了就关闭窗口

​ sideOutputLateDate()——放到侧输出流

时间语义

​ Event Time:事件创建的时间

​ Ingestion Time:数据进入Flink的时间

​ Processing Time:执行操作算子的本地系统时间,与机器有关

水位线(Watermark)

遇到一个时间戳达到了窗口关闭时间,不应该立刻触发窗口计算,而是等待一段时间,等迟到的数据来了再关闭窗口

​ 1. Watermark 是一种衡量 EventTime 进展的机制,可以设定延迟触发

​ 2. Watermark 是用于处理乱序事件的,而正确的处理乱序事件,通常用 Watermark 机制结合 window 来实现

​ 3. 数据流中的 Watermark 用于表示 timestamp 小于 Watermark 的数据,都已经到达了,因此,window 的执行也是由 Watermark 触发的

​ 4. watermark 用来让程序自己平衡延迟和结果正确性

watermark的特点

  1. watermark 是一条特殊的数据记录
  2. watermark 必须单调递增,以确保任务的事件时间时钟在向前推进,而不是在后退
  3. watermark 与数据的时间戳相关

watermark的设定

1. 在Flink中,watermark由应用程序开发人员生成,这通常要对相应的领域有一定的了解
2. 如果watermark设置的延迟太久,收到结果的速度可能就会很慢,解决办法是在水位线到达之前输出一个近似结果
3. 如果watermark到达得太早,则可能收到错误结果,不过Flink处理迟到数据的机制可以解决这个问题

watermark的生成

1. 间断性生成:每来一条就会生成
2. 周期性生成

窗口起始点和偏移量

状态管理

  1. 算子状态

    1. 键控状态

状态后端

一致性检查点

​ Flink故障恢复机制的核心,就是应用状态的一致性检查点

​ 有状态流应用的一致检查点,其实就是所有任务的状态,在某个时间点的一份拷贝(快照);这个时间点,应该是所有任务都恰好处理完一个相同的输入数据的时候

​ 在执行流应用程序期间,Flink会定期保存状态的一致检查点

​ 如果发生故障,Flink 将会使用最近的检查点来一致恢复应用程序的状态,并重新启动处理流程

检查点的实现算法

—— 一种简单的想法:暂停应用,保存状态到检查点,再重新恢复应用

—— Flink的改进实现:基于Chandy-Lamport算法的分布式快照,将检查点的保存和数据处理分离开,不暂停整个应用

​ 分界线对齐:barrier向下游传递,sum任务会等待所有输入分区的barrier到达

​ 对于barrier已经到达的分区,继续到达的数据会被缓存

​ 而barrier尚未到达的分区,数据会被正常处理

​ 当收到所有输入分区的barrier时,任务就将其状态保存到状态后端的检查点中,然后将barrier继续向下游转发

​ Sink任务向JobManager确认状态保存到checkpoint完毕

​ 当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了

保存点

​ Flink提供了自定义的镜像保存功能,就是保存点。

​ 保存点就是具有一些额外元数据的检查点。

​ Flink不会自动创建保存点,用户必须明确地触发创建操作。

​ 保存点可以故障恢复,可以用于:有计划的手动备份,更新应用程序,版本迁移,暂停和重启应用,等等

状态一致性

​ 有状态的流处理,内部每个算子任务都可以有自己的状态

​ 对于流处理器内部来说,所谓的状态一致性,其实就是我们所说的计算结果要保证准确

​ 一条数据不应该丢失,也不应该重复计算

​ 在遇到故障时可以恢复状态,恢复以后的重新计算,结果应该也是完全正确的

状态一致性分类

​ AT-MOST-ONCE(最多一次):当任务故障时,什么都不干,既不恢复丢失的状态,也不重播丢失的数据

​ AT-LEAST-ONCE(至少一次):不丢失事件,所有的事件都得到了处理,而一些事件还可能被处理多次

​ EXACT-ONCE(精确一次):恰好处理一次是最严格的保证,也是最难实现的。恰好处理一次语义不仅仅意味着没有事件丢失,还意味着针对每一个数据,内部状态仅仅更新一次

端到端exactly-once

1. 内部保证:checkpoint
2. source端:可重设数据的读取位置。状态回滚后,source端重设到回滚后的位置
3. sink端:从故障恢复时,数据不会重复写入外部系统
  	1. 幂等写入
  	2. 事务写入:预写日志Write-Ahead-Log Wal + 两阶段提交Two-Phase-Commit 2PC

Flink+Kafka端到端状态一致性的保证

1. 内部:利用checkpoint机制,把状态存盘,发生故障时可以恢复,保证内部的状态一致性
2. source:kafka consumer作为source,可以将偏移量保存下来,如果后续任务出现了故障,恢复的时候可以由连接器重置偏移量,重新消费数据,保证一致性
3. sink:kafka producer作为sink,采用两阶段提交sink,需要实现一个TwoPhraseCommitSinkFunction

Table API 和 Flink SQL

更新模式

​ 追加模式(Append)

​ 撤回模式(Retract)

​ 更新插入模式(Upsert)

流式表查询的处理过程

1. 流被转换为动态表
2. 对动态表计算连续查询,生成新的动态表
3. 生成的动态表被转换回流
posted @ 2024-01-30 12:53  停不下的时光  阅读(12)  评论(0编辑  收藏  举报