🍋🍋大数据学习🍋🍋
🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。
💖如果觉得博主的文章还不错的话,请点赞👍+收藏⭐️+留言📝支持一下博主哦🤞
🍋一、Flink and Spark基本原理
Flink 和 Spark Streaming 都是用于实时流式数据处理的分布式计算框架,但两者的基本设计思想和内部执行机制有些不同。
Flink 基于流的理念,采用了基于数据流模型的核心运行时引擎。它可以对无界和有界数据流进行有状态的计算。Flink 使用了链式操作来表达运算逻辑,并基于流水线的方式进行任务调度。
Spark Streaming 则是通过微批处理的方式来实现对实时数据流的处理。它将数据流切分成很小的批数据,然后提交给 Spark 执行批处理任务。Spark Streaming 基于 RDD 来表达运算逻辑,并通过 Spark 的任务调度机制进行调度。
Flink 的内部把流处理算法表示为数据流图,并以流水线的方式持续运算。而 Spark Streaming 是将流任务拆解为一个个小批的 Spark 任务,这些批任务按时间顺序执行。
两者在 fault tolerance 机制上也有区别。Flink 基于检查点机制实现了 exactly-once 语义。而 Spark Streaming 通过 Write ahead logs 实现了至少一次保证。
实现机制
- 数据处理模式上,Flink 是基于流的真正runtime,可以持续地对无界数据流进行计算。Spark Streaming 则采用的是微批处理模型,将数据流离散为批进行处理。
- Flink 通过aperator chains实现了流式数据流水线计算。Spark Streaming基于RDD拼接批结果来模拟流计算。
- Flink 使用轻量级的流水线调度机制进行任务调度。Spark Streaming则依赖Spark Engine进行任务调度。
- Flink检查点机制实现了Exactly-once语义。Spark Streaming通过Write Ahead Logs实现了至少一次保证。
- Flink基于数据流图进行计算,允许循环数据流(迭代计算)。Spark Streaming的DAG不允许存在循环。
- Flink有更低的延迟,可以达到毫秒级。Spark Streaming批间隔一般在500毫秒以上。
- Flink有更好的重启能力,可以从检查点恢复状态。Spark Streaming重启后需要重新计算。
- Flink有更多针对流的优化,如窗口机制等。Spark Streaming继承自Spark的批设计。
- Flink需要额外的Cluster部署和操作。Spark Streaming可以直接基于Spark Cluster运行。
🍋二、运行角色
Spark Streaming 运行时的角色(standalone 模式)主要有:
Master:主要负责整体集群资源的管理和应用程序调度;
Worker:负责单个节点的资源管理,driver 和 executor 的启动等;
Driver:用户入口程序执行的地方,即 SparkContext 执行的地方,主要是 DGA 生成、stage 划分、task 生成及调度;
Executor:负责执行 task,反馈执行状态和执行结果。
Flink 运行时的角色(standalone 模式)主要有:
Jobmanager: 协调分布式执行,他们调度任务、协调 checkpoints、协调故障恢复等。至少有一个 JobManager。高可用情况下可以启动多个 JobManager,其中一个选举为 leader,其余为 standby;
Taskmanager: 负责执行具体的 tasks、缓存、交换数据流,至少有一个 TaskManager;
Slot: 每个 task slot 代表 TaskManager 的一个固定部分资源,Slot 的个数代表着 taskmanager 可并行执行的 task 数。
🍋三、spark streaming和Flink运行模型
1.Spark Streaming 是微批处理,运行的时候需要指定批处理的时间,每次运行 job 时处理一个批次的数据,流程如图 3 所示:
2.Flink 是基于事件驱动的,事件可以理解为消息。事件驱动的应用程序是一种状态应用程序,它会从一个或者多个流中注入事件,通过触发计算更新状态,或外部动作对注入的事件作出反应。
🍋四、任务调度
1.Spark 任务调度
Spark Streaming 任务如上文提到的是基于微批处理的,实际上每个批次都是一个 Spark Core 的任务。对于编码完成的 Spark Core 任务在生成到最终执行结束主要包括以下几个部分:
构建 DGA 图;
划分 stage;
生成 taskset;
调度 task。
对于 job 的调度执行有 fifo 和 fair 两种模式,Task 是根据数据本地性调度执行的。 假设每个 Spark Streaming 任务消费的 kafka topic 有四个分区,中间有一个 transform操作(如 map)和一个 reduce 操作。
假设有两个 executor,其中每个 executor 三个核,那么每个批次相应的 task 运行位置是固定的吗?是否能预测? 由于数据本地性和调度不确定性,每个批次对应 kafka 分区生成的 task 运行位置并不是固定的。
2.Flink 任务调度
对于 flink 的流任务客户端首先会生成 StreamGraph,接着生成 JobGraph,然后将 jobGraph 提交给 Jobmanager 由它完成 jobGraph 到 ExecutionGraph 的转变,最后由 jobManager 调度执行。
上图所示有一个由 data source、MapFunction和 ReduceFunction 组成的程序,data source 和 MapFunction 的并发度都为 4,而 ReduceFunction 的并发度为 3。一个数据流由 Source-Map-Reduce 的顺序组成,在具有 2 个TaskManager、每个 TaskManager 都有 3 个 Task Slot 的集群上运行。
可以看出 flink 的拓扑生成提交执行之后,除非故障,否则拓扑部件执行位置不变,并行度由每一个算子并行度决定,类似于 storm。而 spark Streaming 是每个批次都会根据数据本地性和资源情况进行调度,无固定的执行拓扑结构。 flink 是数据在拓扑结构里流动执行,而 Spark Streaming 则是对数据缓存批次并行处理。