Spark Structured Streaming 的Continuous模式是Spark 2.3 引入的一种持续计算模型。相比于之前的微批处理达到10ms内的延迟。
首先还是展示 一个example:
import java.util
import java.util.UUID
import com.alibaba.fastjson.JSON
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.streaming.Trigger
import org.apache.spark.sql.types.{DataTypes, StructField, StructType}
import scala.collection.mutable
object ContinuousStructuredKafkaWordCount {
def main(args: Array[String]): Unit = {
val checkpointLocation =
if (args.length > 3) args(3) else "/tmp/temporary-" + UUID.randomUUID.toString
val spark = SparkSession
.builder
.master("local[3]")
.appName("ContinuousStructuredKafkaWordCount")
.enableHiveSupport()
.getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
val lines = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "localhost:9092")
.option("subscribe", "orders")
.option("groupId", "groupID0234")
.load()
.selectExpr("CAST(offset AS STRING)", "CAST(value AS STRING)")// 没有转换则是字节数组
.toDF("offset", "value")
.toDF("value", "id")
// .withWatermark("timestamp", "10 seconds")
val output = lines.selectExpr("value").writeStream
.format("kafka")
.outputMode("append")
.option("kafka.bootstrap.servers", "localhost:9092")
.option("topic", "result")
.option("checkpointLocation", checkpointLocation)
.trigger(Trigger.Continuous("1 second")) // only change in query
//.trigger( Trigger.ProcessingTime("5 seconds")) // only change in query
.start()
output.awaitTermination()
}
}
由代码可见,与批处理Trigger的ProcessingTime 相比,不需要改动其他代码,只需要将Trigger改为Continuous模式。这里注意一下,1 second 代表 1秒进行一次状态保存,而非批次处理间隔时间。
Continuous模式目前仍有其他约束:
1.只能进行简单的map类型的操作,不能涉及到shuffle(例如join)
因此现在可以做为数据流处理中的一个中转站。只对数据做一层低延迟的简单解析。例如解析Kafka内非结构化的日志,生成json结构的结构化数据,再次存到Kafka。
具体Continuous 原理下次解析。