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 包括 StreamOperator
  2. 转换操作符(Transformation Operator)把一个或多个 Stream 转换成多个 Stream
  3. 每个 Streaming Dataflow 都有一个输入数据源(Source)和一个输出数据源(Sink
  4. Streaming DataflowSpark RDD DAG 类似,会被组合成一个 DAG 去执行

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

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

image-20241118233145416

StreamOperator 之间传输数据的形式有两种

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

架构

image-20241118234718318

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

Flink vs Spark

FlinkSpark 都支持批处理流处理

相同点

  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 SQLTable API 提供 SQL 支持
  2. Spark 对 SQL 支持更好,相应的优化扩展性能更好

迭代计算

Flink

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

生态

Spark

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

场景

Spark

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