结构化流式聚合返回错误的值

时间:2017-09-14 14:47:29

标签: apache-spark cassandra spark-structured-streaming

我编写了一个结构化流式聚合,它从Kafka源获取事件,执行简单计数并将它们写回Cassandra数据库。代码如下所示:

val data = stream
  .groupBy(functions.to_date($"timestamp").as("date"), $"type".as("type"))
  .agg(functions.count("*").as("value"))

val query: StreamingQuery = data
  .writeStream
  .queryName("group-by-type")
  .format("org.apache.spark.sql.streaming.cassandra.CassandraSinkProvider")
  .outputMode(OutputMode.Complete())
  .option("checkpointLocation", config.getString("checkpointLocation") + "/" + "group-by-type")
  .option("keyspace", "analytics")
  .option("table", "aggregations")
  .option("partitionKeyColumns", "project,type")
  .option("clusteringKeyColumns", "date")
  .start()

问题在于计数刚好超过每一批。所以我会看到Cassandra的数量下降。计数永远不会超过一天,我怎么能实现呢?

编辑: 我也试过使用窗口聚合,同样的事情

1 个答案:

答案 0 :(得分:0)

所以这种情况下的错误实际上并不在我的查询或Spark中。 为了找出问题所在,我使用了控制台接收器并且没有显示问题。

问题发生在我的Cassandra水槽里,看起来像这样:

class CassandraSink(sqlContext: SQLContext, keyspace: String, table: String) extends Sink {
  override def addBatch(batchId: Long, data: DataFrame): Unit = {
    data.write.mode(SaveMode.Append).cassandraFormat(table, keyspace).save()
  }
}

它使用Datastax Spark Cassandra连接器来写入数据帧。

问题是变量data包含流数据集。在Spark提供的ConsoleSink中,DataSet在写入之前被复制到静态DataSet中。所以我改变了它,现在它起作用了。完成版本如下所示:

class CassandraSink(sqlContext: SQLContext, keyspace: String, table: String) extends Sink {
  override def addBatch(batchId: Long, data: DataFrame): Unit = {
    val ds = data.sparkSession.createDataFrame(
      data.sparkSession.sparkContext.parallelize(data.collect()),
      data.schema
    )
    ds.write.mode(SaveMode.Append).cassandraFormat(table, keyspace).save()
  }
}