Я использую Spark structured streaming для обработки записей, считанных с Kafka. Вот чего я пытаюсь достичь:
(a) Каждая запись является Tuple2 типа (Timestamp, DeviceId).
(b) Я создал статический Dataset[DeviceId], который содержит набор всех допустимых идентификаторов устройств (типа DeviceId), которые, как ожидается, будут отображаться в потоке Kafka.
(c) Мне нужно написать запрос Spark structured streaming, который
(i) Groups records by their timestamp into 5-minute windows
(ii) For each window, get the list of valid device IDs that were **not** seen in that window
Например, допустим, что список всех допустимых идентификаторов устройства [A,B,C,D,E], а записи кафки в определенном 5-минутном окне содержат идентификаторы устройств [A,B,E]. Затем для этого окна список невидимых идентификаторов устройств, которые я ищу, это [C,D].
Вопрос
- Как этот запрос может быть написан в Spark-структурированной потоковой передаче? Я попытался использовать методы
except()иjoin(), которые предоставляетDataset. Тем не менее, они оба бросили исключение во время выполнения, жалуясь, что ни одна из этих операций не поддерживается наstreaming Dataset.
Вот фрагмент моего кода:
val validDeviceIds: Dataset[(DeviceId, Long)] = spark.createDataset[DeviceId](listOfAllDeviceIds.map(id => (id, 0L)))
case class KafkaRecord(timestamp: TimestampType, deviceId: DeviceId)
// kafkaRecs is the data stream from Kafka - type is Dataset[KafkaRecord]
val deviceIdsSeen = kafkaRecs
.withWatermark("timestamp", "5 minutes")
.groupBy(window($"timestamp", "5 minutes", "5 minutes"), $"deviceId")
.count()
.map(row => (row.getLong(0), 1L))
.as[(Long, Long)]
val unseenIds = deviceIdsSeen.join(validDeviceIds, Seq("_1"), "right_outer")
.filter(row => row.isNullAt(1))
.map(row => row.getLong(0))
Последний оператор выдает следующее исключение:
Caused by: org.apache.spark.sql.AnalysisException: Right outer join with a streaming DataFrame/Dataset on the left is not supported;;
Спасибо заранее.