Java Spark结构化流-在有状态流处理中使用窗口操作的事件处理
我是Spark Structured Streaming processing的新手,目前正在处理一个用例,其中Structured Streaming应用程序将从Azure IoT Hub Event Hub获取事件(比如每20秒一次) 任务是使用这些事件并实时处理它。为此,我在下面用Spark Java编写了Spark结构化流媒体程序 以下是要点Java Spark结构化流-在有状态流处理中使用窗口操作的事件处理,java,apache-spark,spark-structured-streaming,Java,Apache Spark,Spark Structured Streaming,我是Spark Structured Streaming processing的新手,目前正在处理一个用例,其中Structured Streaming应用程序将从Azure IoT Hub Event Hub获取事件(比如每20秒一次) 任务是使用这些事件并实时处理它。为此,我在下面用Spark Java编写了Spark结构化流媒体程序 以下是要点 目前我已经应用了10分钟的窗口操作 间隔和5分钟滑动窗口 水印以10分钟的间隔应用于eventDate参数 目前我没有执行任何其他操作,只是将其存
公共类事件订阅服务器{
公共静态void main(字符串args[])抛出InterruptedException、StreamingQueryException{
字符串eventHubCompatibleEndpoint=“”;
String connString=新连接StringBuilder(eventHubCompatibleEndpoint).build();
EventHubsConf EventHubsConf=新的EventHubsConf(connString).setConsumerGroup($Default)
.setStartingPosition(EventPosition.fromEndOfStream()).setMaxRatePerPartition(100)
.setReceiverTimeout(java.time.Duration.ofMinutes(10));
SparkConf SparkConf=new SparkConf().setMaster(“本地[2]”)。setAppName(“IoT火花流”);
SparkSession spSession=SparkSession.builder()
.appName(“物联网火花流”)
.config(sparkConf.config(“spark.sql.streaming.checkpointLocation”,”)
.getOrCreate();
数据集inputStreamDF=spSession.readStream()
.格式(“事件中心”)
.options(eventHubsConf.toMap())
.load();
Dataset bodyRow=inputStreamDF.withColumn(“body”,新列(“body”).cast(DataTypes.StringType))。选择(“body”);
StructType jsonStruct=new StructType()
.add(“eventType”,数据类型.StringType)
.add(“有效载荷”,数据类型.StringType);
Dataset messageRow=bodyRow.map((MapFunction)值->{
字符串VALTR=value.getString(0.toString();
字符串有效载荷=VALTR;
Gson Gson=new GsonBuilder().serializeNulls().setPrettyPrinting().create();
JsonObject jsonObj=gson.fromJson(valStr,JsonObject.class);
JsonElement methodName=jsonObj.get(“方法”);
字符串eventType=null;
if(methodName!=null){
eventType=“其他_事件”;
}否则{
eventType=“设备\事件”;
}
Row jsonRow=RowFactory.create(事件类型,有效负载);
返回jsonRow;
},rowcoder.apply(jsonStruct));
messageRow.printSchema();
Dataset deviceEventRowDS=messageRow.filter(“eventType='DEVICE\u EVENT'”);
deviceEventRowDS.printSchema();
数据集deviceEventDS=deviceEventRowDS.map((MapFunction)值->{
字符串jsonString=value.getString(1.toString();
Gson Gson=new GsonBuilder().serializeNulls().setPrettyPrinting().create();
DeviceMessage DeviceMessage=gson.fromJson(jsonString,DeviceMessage.class);
DeviceEvent DeviceEvent=deviceMessage.getDeviceEvent();
返回设备事件;
}bean(DeviceEvent.class));
deviceEventDS.printSchema();
Dataset messageDataset=deviceEventDS.select(
functions.col(“eventType”),
函数col(“deviceID”),
函数。col(“说明”),
functions.to_时间戳(functions.col(“eventDate”),“yyyy-MM-dd hh:MM:ss”).as(“eventDate”),
functions.col(“deviceModel”),
函数。col(“pingRate”))
。选择(“事件类型”、“设备ID”、“说明”、“事件日期”、“设备模型”、“pingRate”);
messageDataset.printSchema();
Dataset devindowDataSet=messageDataset.withWatermark(“eventDate”,“10分钟”)
.groupBy(functions.col(“deviceID”),
函数窗口(
functions.col(“eventDate”)、“10分钟”、“5分钟”)
.count();
devWindowDataset.printSchema();
StreamingQuery query=devindowDataSet.writeStream().outputMode(“追加”)
.格式(“拼花地板”)
.选项(“截断”、“假”)
.选项(“路径”,“路径”)
.start();
query.waittermination();
}}
任何与此相关的帮助或指导都是有用的
感谢和问候
阿维纳什·德什穆克
是否可以根据窗口时间以拼花格式将多个事件存储在一个文件中
对
在这种情况下,窗口操作是如何工作的
以下代码是Spark结构化流媒体应用程序的主要部分:
Dataset<Row> devWindowDataset = messageDataset
.withWatermark("eventDate", "10 minutes")
.groupBy(
functions.col("deviceID"),
functions.window(functions.col("eventDate"), "10 minutes", "5 minutes"))
.count();
Dataset devindowDataSet=messageDataset
.withWatermark(“事件日期”,“10分钟”)
.群比(
函数col(“deviceID”),
functions.window(functions.col(“eventDate”)、“10分钟”、“5分钟”)
.count();
也就是说,底层状态存储应根据deviceID
和eventDate
将状态保持10分钟,对于延迟事件,额外的10分钟(根据带水印
)。换言之,在流式查询开始20分钟后,您应该会看到一个事件出现eventDate
20分钟的结果
withWatermark
适用于延迟事件,因此即使groupBy
会产生结果,结果也不会仅在超过水印阈值时才会发出
Dataset<Row> devWindowDataset = messageDataset
.withWatermark("eventDate", "10 minutes")
.groupBy(
functions.col("deviceID"),
functions.window(functions.col("eventDate"), "10 minutes", "5 minutes"))
.count();