Spark 实时性

  1. 无论是 Spark Streaming 还是 Structured Streaming,Spark 流处理的实时性还不够
    • 无法应对实时性要求很高的流处理场景
  2. Spark 的流处理是基于微批处理的思想
    • 把流处理看做批处理的一种特殊形式,没接收到一个时间间隔的数据才会去处理
  3. 虽然在 Spark 2.3 中提出连续处理模型,但只支持有限的功能,并不能在大项目中使用
  4. 要在流处理的实时性提升,就不能继续用微批处理的模式,而是有数据数据就立即处理,不做等待
    • Apache Flink 采用了基于操作符(Operator)的连续流模型,可以做到微秒级别的延迟

Flink

模型

  1. Flink 中最核心的数据结构是 Stream,代表一个运行在多个分区上的并行流
  2. 在 Stream 上可以进行各种转换(Transformation)操作
  3. 与 Spark RDD 不同的是,Stream 代表一个数据流而不是静态数据的集合
    • Stream 所包含的数据随着时间增长而变化的
    • 而且 Stream 上的转换操作都是逐条进行的 - 每当有新数据进入,整个流程都会被执行并更新结果
    • Flink 比 Spark Streaming 有更低的流处理延迟性

当一个 Flink 程序被执行时,会被映射为 Streaming Dataflow

image-20241118232520584

  1. Streaming Dataflow 包括 Stream 和 Operator
  2. 转换操作符(Transformation Operator)把一个或多个 Stream 转换成多个 Stream
  3. 每个 Streaming Dataflow 都有一个输入数据源(Source)和一个输出数据源(Sink)
  4. Streaming Dataflow 与 Spark RDD DAG 类似,会被组合成一个 DAG 去执行

在 Flink 中,程序天生就是并行和分布式的

  1. 一个 Stream 可以包含多个分区(Stream Partitions)
  2. 一个 Operator 可以被分成多个 Operator 子任务
    • 每一个子任务在不同的线程或者不同的节点上独立执行

image-20241118233145416

Stream 在 Operator 之间传输数据的形式有两种

  1. 一对一(One-to-one)
    • Stream 维护着分区和元素的顺序
    • Map Operator 的子任务处理的数据和 Source 的子任务生产的元素的数据相同
    • 与 Spark RDD 窄依赖非常类似
  2. 重新分布(Redistributing)
    • Stream 中数据的分区会发生改变
    • Operator 的每个子任务把数据发送到不同的目标子任务上

架构

image-20241118234718318

  1. 核心处理引擎是 Distributed Streaming Dataflow
    • 所有高级 API 和应用库都会被翻译成包含 Stream 和 Operator 的 Streaming Dataflow
  2. Flink 提供两个核心的 API - DataSet API 和 DataStream API
    • 与 Spark 的 DataSet 和 DataFrame 非常类似
    • DataSet 代表有界的数据集,而 DataStream 代表流数据
    • DataSet API 用来做批处理,而 DataStream API 用来做流处理
  3. 在 Flink 内部,DataSet 其实也是用 Stream 表示
    • 静态的有界数据可以被看作特殊的流数据 – 刚好与 Spark 相反
    • DataSet 与 DataStream 可以无缝切换 - Flink 的核心是 DataStream
  4. DataSet 和 DataStream 都支持各种基本的转换操作 - map、filter、count、groupBy 等
  5. Flink 是用 Java 开发的,对 Java 有原生的支持,也可以用 Scala 开发 Flink 程序
    • 在 Flink 1.0 后支持了 Python
  6. Flink DataStream 的使用方法与 Spark RDD 类似
    • 把程序拆分成一系列的转换操作并分布式地执行
  7. 在 DataSet 和 DataStream 之上,有更高层次的 Table API
    • Flink Table API 与 Spark SQL 的思想类似,是关系型的 API
    • 可以像操作 SQL 数据库表那样操作数据,而不需要通过操作 DataStream/DataSet 的方式进行数据处理
    • 更不需要手动优化代码的执行逻辑
    • 跟 Spark SQL 类似,Flink Table API 同样统一了 Flink 的批处理和流处理

Flink vs Spark

Flink 和 Spark 都支持批处理和流处理

相同点

  1. 都是基于内存计算
  2. 都有统一的批处理和流处理的 API,都支持类似 SQL 的编程接口
  3. 都支持很多相同的转换操作,编程都是用类似 Scala Collection API 的函数式编程模式
  4. 都有完善的错误恢复机制
  5. 都支持 Exactly once 的语义一致性

差异点

流处理

Flink

  1. Spark 是基于微批处理
    • 把流数据看成一个个小的批处理数据块分别处理,延迟性只能做到秒级
    • Spark 只支持基于时间的窗口处理(处理时间或者事件时间)
  2. Flink 是基于每个事件处理
    • 每当有新的数据输入都会立刻处理,是真正的流式计算,支持毫秒级计算
    • Flink 支持的窗口操作非常灵活,不仅支持时间窗口,还支持基于数据本身的窗口

SQL

Spark

  1. Spark 和 Flink 分别提供 Spark SQL 和 Table API 提供 SQL 支持
  2. Spark 对 SQL 支持更好,相应的优化、扩展和性能更好

迭代计算

Flink

  1. Spark 对机器学习的支持很好,可以在内存中缓存中间计算结果来加速机器学习算法的运行
  2. 但大部分机器学习算法其实是个有环的数据流,在 Spark 中,却是用无环图来表示
  3. Flink 支持在运行时间中的有环数据流,从而可以更有效地对机器学习算法进行运算

生态

Spark

  1. Spark 社区更活跃,各种扩展库也更全面

场景

Spark

  1. 数据量非常大而且逻辑复杂的批处理,并且对计算效率有较高要求
  2. 基于历史数据的交互式查询,要求响应较快
  3. 基于实时数据流的数据处理,延迟性要求在百毫秒到数秒之间
  1. Flink 是为了提升流处理而创建的平台,适用于各种需要非常低延迟的实时数据处理场景 - 实时日志分析
  2. Flink 是用流处理去模拟批处理的思想,比 Spark 用批处理去模拟流处理的思想扩展性更好