Apache spark 对delta lake具有多个相同密钥的流写入
我正在通过spark结构化流向delta lake写入流。每个流式批处理包含键值,也包含时间戳作为一列。delta lake不支持在源蒸汽批处理中使用多个相同的键进行更新,所以我只想使用具有最新时间戳的记录来更新delta lake。我该怎么做 这是我正在尝试的代码片段:Apache spark 对delta lake具有多个相同密钥的流写入,apache-spark,spark-streaming,delta-lake,Apache Spark,Spark Streaming,Delta Lake,我正在通过spark结构化流向delta lake写入流。每个流式批处理包含键值,也包含时间戳作为一列。delta lake不支持在源蒸汽批处理中使用多个相同的键进行更新,所以我只想使用具有最新时间戳的记录来更新delta lake。我该怎么做 这是我正在尝试的代码片段: def upsertToDelta(microBatchOutputDF: DataFrame, batchId: Long) { println(s"Executing batch $batchId ...") m
def upsertToDelta(microBatchOutputDF: DataFrame, batchId: Long) {
println(s"Executing batch $batchId ...")
microBatchOutputDF.show()
deltaTable.as("t")
.merge(
microBatchOutputDF.as("s"),
"s.key = t.key")
.whenMatched().updateAll()
.whenNotMatched().insertAll()
.execute()
}
提前感谢。您可以从microBatchOutputDF数据帧中删除具有较旧时间戳的记录,并且只保留具有给定密钥的最新时间戳的记录 您可以使用spark的“reduceByKey”操作并实现如下自定义reduce功能
def getLatestEvents(input: DataFrame) : RDD[Row] = {
input.rdd.map(x => (x.getAs[String]("key"), x)).reduceByKey(reduceFun).map(_._2) }
def reduceFun(x: Row, y: Row) : Row = {
if (x.getAs[Timestamp]("timestamp").getTime > y.getAs[Timestamp]("timestamp").getTime) x else y }
假定键的类型为字符串&时间戳的类型为时间戳。并为您的流媒体批次“microBatchOutputDF”调用getLatestEvents。它忽略较旧的时间戳事件&只保留最新的事件
val latestRecordsDF = spark.createDataFrame(getLatestEvents(microBatchOutputDF), <schema of DF>)
然后在“latestRecordsDF”之上调用deltalake合并操作,在微批次的流媒体中,您可能会获得一个给定密钥的多个记录。为了用目标表更新它,您必须在微批次中找出密钥的最新记录。在本例中,您可以使用max of timestamp列和value列查找最新记录,并将其用于合并操作
有关查找给定密钥的最新记录的更多详细信息,请参阅此部分。将使用相同的方法。谢谢你的回复。