为什么流聚合延迟到总是两批数据为止?

时间:2019-01-26 12:09:45

标签: apache-spark spark-structured-streaming

我使用Spark 2.3.0。

我的问题是,每当我在输入目录中添加第三批数据时,第一批数据就被处理并打印到控制台。为什么?

val spark = SparkSession
  .builder()
  .appName("micro1")
  .enableHiveSupport()
  .config("hive.exec.dynamic.partition", "true")
  .config("hive.exec.dynamic.partition.mode", "nonstrict")
  .config("spark.sql.streaming.checkpointLocation", "/user/sas/sparkCheckpoint")
  .config("spark.sql.parquet.cacheMetadata","false")
  .getOrCreate()

import spark.implicits._
import org.apache.spark.sql.functions._

// Left side of a join
import org.apache.spark.sql.types._
val mySchema = new StructType()
  .add("id", IntegerType)
  .add("name", StringType)
  .add("year", IntegerType)
  .add("rating", DoubleType)
  .add("duration", IntegerType)
val xmlData = spark
  .readStream
  .option("sep", ",")
  .schema(mySchema)
  .csv("tostack")

// Right side of a join
val mappingSchema = new StructType()
  .add("id", StringType)
  .add("megavol", StringType)
val staticData = spark
  .read
  .option("sep", ",")
  .schema(mappingSchema)
  .csv("input_tost_static.csv") 

xmlData.createOrReplaceTempView("xmlupdates")
staticData.createOrReplaceTempView("mappingdata")

spark
  .sql("select * from xmlupdates a join mappingdata b on  a.id=b.id")
  .withColumn(
    "event_time",
    to_utc_timestamp(current_timestamp, Calendar.getInstance().getTimeZone().getID()))
  .withWatermark("event_time", "10 seconds")
  .groupBy(window($"event_time", "10 seconds", "10 seconds"), $"year")
  .agg(
    sum($"rating") as "rating",
    sum($"duration") as "duration",
    sum($"megavol") as "sum_megavol")
  .drop("window")
  .writeStream
  .outputMode("append")
  .format("console")
  .start

我的输出显示数据如下:我先开始流式传输,然后将数据添加到特定文件夹中。当我添加第三个文件时,第一个文件的聚合结果将被打印出来。为什么?

     -------------------------------------------
     Batch: 0
     -------------------------------------------
     +----+------+--------+-----------+
     |year|rating|duration|sum_megavol|
     +----+------+--------+-----------+
     +----+------+--------+-----------+

     -------------------------------------------
     Batch: 1
     -------------------------------------------
     +----+------+--------+-----------+
     |year|rating|duration|sum_megavol|
     +----+------+--------+-----------+
     +----+------+--------+-----------+

     -------------------------------------------
     Batch: 2
     -------------------------------------------
     +----+------+--------+-----------+
     |year|rating|duration|sum_megavol|
     +----+------+--------+-----------+
     |1963|   2.8|    5126|       46.0|
     |1921|   6.0|   15212|     3600.0|
     +----+------+--------+-----------+

输入数据如下:

1,The Nightmare Before Christmas,1993,3.9,4568
2,The Mummy,1993,3.5,4388
3,Orphans of the Storm,1921,3.2,9062
4,The Object of Beauty,1921,2.8,6150
5,Night Tide,1963,2.8,5126
6,One Magic Christmas,1963,3.8,5333
7,Muriel's Wedding,1963,3.5,6323
8,Mother's Boys,1963,3.4,5733

input_tost_static.csv数据集如下:

3,3000
4,600
5,46

有人可以帮我为什么火花结构化流显示这种行为吗?我需要在这里添加任何设置吗? 更新:如果我尝试在JOIN操作之前打印val,我将在批次1中得到结果...问题是在加入后出现的。它延迟了3个批次以上。...

1 个答案:

答案 0 :(得分:-1)

  

我首先开始流式传输

批处理:0 是在您启动查询后立即执行的,并且没有事件流,也就没有输出。

至此,事件时间水印根本没有设置。

  

,然后将数据添加到特定文件夹中。

可能是批次:1

然后将事件时间水印设置为current_timestamp。为了获得任何输出,我们必须等待"10 seconds"(根据withWatermark("event_time", "10 seconds"))。

  

当我添加第三个文件时,将打印第一个文件的聚合结果。为什么?

可能是批次:2

我假设下次您添加新文件时是在上一个current_timestamp + "10 seconds"之后,因此您得到了输出。

请注意,水印只能是0,这意味着不会有延迟数据。