Spark Structured Streaming 编程模型

从Spark 2.0.0开始,提供了一个用于实时流处理的新组件-Structured Streaming(结构化流)

本文总结Structured Streaming的编程模型,顺带会总结Structured Streaming与Spark Streaming的区别。

Structured Streaming 编程模型

  • 首先,Structured Streaming有一个Input Table的概念。即将输入的数据流视为一张Append-Only Input Table表。流式数据源源不断地追加到Input Table表中,每条数据都对应表中的一行。

  • 其次,Structured Streaming有一个Trigger的概念。即多久去检查一次新数据并执行查询。

  • 再次,Structured Streaming有一个Query的概念。即在Input Table上执行各种操作,如map/filter/groupBy/window等等。

  • 然后,Structured Streaming有一个Result Table的概念。即每次Trigger后,会将Query结果更新到Result Table结果表中。

  • 最后,Structured Streaming有一个Output Mode的概念。即每次Trigger后,将Result Table中的哪一部分(Complete(全部)/Append(Append的行)/Update(Update的行))写到外部存储。

  • 注意, Structured Streaming还有一个Checkpoint的概念。通过Checkpoint来跟踪数据源的进度和计算的中间状态,可用于重启或故障后恢复,进而保证计算引擎的EOS语义。

总结,一句话,每次Trigger,会去检查新数据,并追加到Input Table,对Input Table执行Query并更新到Result Table结果表中。最后,按照指定的Output Mode,将结果表中的数据写到外部存储。

以Global WordCount为例,理解Structured Streaming 编程模型。
Spark Structured Streaming 编程模型

Structured Streaming与Spark Streaming的区别

再总结下Structured Streaming与Spark Streaming的区别。

  1. 执行引擎

Spark Streaming是基于RDD构建的,Structured Streaming是基于Spark SQL引擎构建的。

  1. 编程模型

Spark Streaming在编程模型上是真正的微批。Structured Streaming虽然也有微批模式,但从模型上(Input Table、StreamingQuery、Result Table等等)讲,Structured Streaming更像真正的流。

  1. RDD与DataFrame、DataSet、SQL

基于Spark Streaming构建流应用,使用的是DStream API(本质上使用的是RDD API),RDD API是Complex, Low-Level的API,同一个流应用,受限于开发者的水平,最终构建出的DAG,运行效率可能差别很大。Structured Streaming应用则是基于Simple,High-Level的API(DataFrame/DataSet/SQL)构建的,受益于Spark SQL引擎的优化,会有更高的性能。

  1. Processing Time与Event Time

Spark Streaming默认支持的是基于Processing Time(处理时间)的处理,要想在Spark Streaming上实现基于Event Time(事件时间)的处理并解决Late Data(迟到数据)的问题,会非常复杂。Structured Streaming除了支持基于Processing Time(处理时间)的处理外,还提供了基于Event Time(事件时间)的处理,使得这一场景变得很简单。

  1. End To End的语义保证

Spark Streaming能保证自身是Exactly-Once,但Spark Streaming接入数据和输出到外部存储,往往还需要用户自己去保证,如Spark Streaming接入Kafka数据,一般还需要自己维护Kafka Offset。Structured Streaming结合Checkpoint和支持Replayable的数据源、支持Idempotent的目的地,使得End-To-End Exactly-Once语义保证更加容易。

  1. Sink

在Spark Streaming中,要输出到外部存储,都需要通过foreachRDD方法来自己编程实现每个批次的数据输出。在Structured Streaming中,默认已经提供了一些Sink,如Console Sink、File Sink、Kafka Sink等,只要通过简单配置,即可使用;如果提供的Sink不满足,实现ForeachWriter/foreachBatch接口,自定义Sink即可。

  1. 批流统一

现在都在提倡批流统一,在Spark Streaming中,想把流式的DSteam应用转换成批处理的RDD,代价还是很大的。在Structured Streaming中,由于流式应用是基于DataFrame/DataSet/SQL开发的,所以能很容易的转换成批处理。