对于 MapReduce 和 Spark 来讲,这些数据是一大批数据,也称之为有界数据,对这些数据的计算就称为批计算。
随着移动互联网、物联网的兴起,每分每秒都在产生大量的数据,例如传感器产生的数据、订单交易数据、用户行为记录等。这些无时不刻都在产生的数据,我们称之为无界数据或流数据。通常被用于用户行为分析进行实时推荐、销售数据实时分析进行营销策略调整等场景。
MapReduce 和 Spark 这样的批计算系统就满足不了实时计算的需求。所以就诞生了 Storm、Spark Streaming、Flink这些流计算系统。
批计算和流计算整体工作流程大体一致,都有任务调度、计算结果聚合等过程。只不过因为数据源的原因,执行细节上会有所不同。这里有几个概念需要进行区分,避免混淆:
- 资源(计算节点)分配:
批计算是对一批数据进行一次计算,所以在每次调度计算任务时分配资源,计算完成后,对应的资源就会被释放,下次在执行时重新分配资源。
流计算是对实时流进系统的数据进行不间断的计算,所以计算资源会一次分配完成,后续的计算任务会一直运行,直到程序异常任务停止才会释放资源。
- 任务调度:
- 批计算是因为历史数据量过大,数据源是分布在各个节点的数据块,所以会根据数据所在地进行任务调度(数据、计算本地化)。
- 流计算数据源通常是Socket、Kafka中的一条条数据,所有的计算任务在这之前已经根据并行度调度到各个节点,数据来临时根据某个策略分配给某个计算任务。
由于 Spark Streaming 是建立在 Spark 基础上,所以任务执行还是 Spark 的逻辑,所以 Spark Streaming 算是一个“伪”流计算系统,属于批计算这一波。
简单来说 Spark Streaming 通过很小的时间间隔(例如1秒)将实时数据收集为“微批”数据,然后然后交给 Spark 处理。
Spark Streaming 微批数据
因为是间隔一段时间再去计算,所以在实时性方面,Spark Streaming 就不如 Flink,现在说起流计算基本上就是在讨论 Flink 了。不过两者的架构和概念有很多相似的地方,也都是函数式编程。如果掌握了 Spark ,学习 Flink 也就非常简单轻松了。
至于 Storm ,作为早期的实时计算引擎并不支持有状态计算和exactly-once的语义,以及编码相对复杂,所以现在也慢慢被大家遗忘。
如果有“Spark Streaming 收集的数据是怎么分区的?”、“什么是有状态计算和exactly-once语义?”、“Flink 是如何做到数据、计算本地化?”