Big Data - Spark + Flink
Spark 实时性
- 无论是 Spark Streaming 还是 Structured Streaming,Spark 流处理的实时性还不够
- 无法应对实时性要求很高的流处理场景
- Spark 的流处理是基于微批处理的思想
- 把流处理看做批处理的一种特殊形式,没接收到一个时间间隔的数据才会去处理
- 虽然在 Spark 2.3 中提出连续处理模型,但只支持有限的功能,并不能在大项目中使用
- 要在流处理的实时性提升,就不能继续用微批处理的模式,而是有数据数据就立即处理,不做等待
- Apache Flink 采用了基于操作符(Operator)的连续流模型,可以做到微秒级别的延迟
Flink
模型
- Flink 中最核心的数据结构是 Stream,代表一个运行在多个分区上的并行流
- 在 Stream 上可以进行各种转换(Transformation)操作
- 与 Spark RDD 不同的是,Stream 代表一个数据流而不是静态数据的集合
- Stream 所包含的数据随着时间增长而变化的
- 而且 Stream 上的转换操作都是逐条进行的 - 每当有新数据进入,整个流程都会被执行并更新结果
- Flink 比 Spark Streaming 有更低的流处理延迟性
当一个 Flink 程序被执行时,会被映射为 Streaming Dataflow
- Streaming Dataflow 包括 Stream 和 Operator
- 转换操作符(Transformation Operator)把一个或多个 Stream 转换成多个 Stream
- 每个 Streaming Dataflow 都有一个输入数据源(Source)和一个输出数据源(Sink)
- Streaming Dataflow 与 Spark RDD DAG 类似,会被组合成一个 DAG 去执行
在 Flink 中,程序天生就是并行和分布式的
- 一个 Stream 可以包含多个分区(Stream Partitions)
- 一个 Operator 可以被分成多个 Operator 子任务
- 每一个子任务在不同的线程或者不同的节点上独立执行
Stream 在 Operator 之间传输数据的形式有两种
- 一对一(One-to-one)
- Stream 维护着分区和元素的顺序
- Map Operator 的子任务处理的数据和 Source 的子任务生产的元素的数据相同
- 与 Spark RDD 窄依赖非常类似
- 重新分布(Redistributing)
- Stream 中数据的分区会发生改变
- Operator 的每个子任务把数据发送到不同的目标子任务上
架构
- 核心处理引擎是 Distributed Streaming Dataflow
- 所有高级 API 和应用库都会被翻译成包含 Stream 和 Operator 的 Streaming Dataflow
- Flink 提供两个核心的 API - DataSet API 和 DataStream API
- 与 Spark 的 DataSet 和 DataFrame 非常类似
- DataSet 代表有界的数据集,而 DataStream 代表流数据
- DataSet API 用来做批处理,而 DataStream API 用来做流处理
- 在 Flink 内部,DataSet 其实也是用 Stream 表示
- 静态的有界数据可以被看作特殊的流数据 – 刚好与 Spark 相反
- DataSet 与 DataStream 可以无缝切换 - Flink 的核心是 DataStream
- DataSet 和 DataStream 都支持各种基本的转换操作 - map、filter、count、groupBy 等
- Flink 是用 Java 开发的,对 Java 有原生的支持,也可以用 Scala 开发 Flink 程序
- 在 Flink 1.0 后支持了 Python
- Flink DataStream 的使用方法与 Spark RDD 类似
- 把程序拆分成一系列的转换操作并分布式地执行
- 在 DataSet 和 DataStream 之上,有更高层次的 Table API
- Flink Table API 与 Spark SQL 的思想类似,是关系型的 API
- 可以像操作 SQL 数据库表那样操作数据,而不需要通过操作 DataStream/DataSet 的方式进行数据处理
- 更不需要手动优化代码的执行逻辑
- 跟 Spark SQL 类似,Flink Table API 同样统一了 Flink 的批处理和流处理
Flink vs Spark
Flink 和 Spark 都支持批处理和流处理
相同点
- 都是基于内存计算
- 都有统一的批处理和流处理的 API,都支持类似 SQL 的编程接口
- 都支持很多相同的转换操作,编程都是用类似 Scala Collection API 的函数式编程模式
- 都有完善的错误恢复机制
- 都支持 Exactly once 的语义一致性
差异点
流处理
Flink
- Spark 是基于微批处理
- 把流数据看成一个个小的批处理数据块分别处理,延迟性只能做到秒级
- Spark 只支持基于时间的窗口处理(处理时间或者事件时间)
- Flink 是基于每个事件处理
- 每当有新的数据输入都会立刻处理,是真正的流式计算,支持毫秒级计算
- Flink 支持的窗口操作非常灵活,不仅支持时间窗口,还支持基于数据本身的窗口
SQL
Spark
- Spark 和 Flink 分别提供 Spark SQL 和 Table API 提供 SQL 支持
- Spark 对 SQL 支持更好,相应的优化、扩展和性能更好
迭代计算
Flink
- Spark 对机器学习的支持很好,可以在内存中缓存中间计算结果来加速机器学习算法的运行
- 但大部分机器学习算法其实是个有环的数据流,在 Spark 中,却是用无环图来表示
- Flink 支持在运行时间中的有环数据流,从而可以更有效地对机器学习算法进行运算
生态
Spark
- Spark 社区更活跃,各种扩展库也更全面
场景
Spark
- 数据量非常大而且逻辑复杂的批处理,并且对计算效率有较高要求
- 基于历史数据的交互式查询,要求响应较快
- 基于实时数据流的数据处理,延迟性要求在百毫秒到数秒之间
Flink
- Flink 是为了提升流处理而创建的平台,适用于各种需要非常低延迟的实时数据处理场景 - 实时日志分析
- Flink 是用流处理去模拟批处理的思想,比 Spark 用批处理去模拟流处理的思想扩展性更好
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.