我有一个用例,在MySQL中连续插入有关传感器的事件信息。我们需要每隔1或2分钟在Kafka主题中通过一些处理发送此信息。
我正在使用Spark将此信息发送到Kafka主题并在Phoenix表中维护CDC。我正在使用Cron作业每1分钟运行一次火花作业。
我目前面临的问题是消息排序,我需要在升序时间戳中发送这些消息以结束系统Kafka主题(它有1个分区)。但是由于多个spark DataFrame分区同时向Kafka主题发送信息,大多数消息排序都会丢失。
目前作为一种解决方法,我将我的DataFrame重新分区为1,以便维护消息排序,但这不是一个长期的解决方案,因为我正在失去火花分布式计算。
如果你们有更好的解决方案设计,请建议。
答案 0 :(得分:0)
我可以通过提升时间戳来实现消息排序,通过使用密钥修复我的数据并在分区中应用排序。
val pairJdbcDF = jdbcTable.map(row => ((row.getInt(0), row.getString(4)), s"${row.getInt(0)},${row.getString(1)},${row.getLong(2)},${row. /*getDecimal*/ getString(3)},${row.getString(4)}"))
.toDF("Asset", "Message")
val repartitionedDF = pairJdbcDF.repartition(getPartitionCount, $"Asset")
.select($"Message")
.select(expr("(split(Message, ','))[0]").cast("Int").as("Col1"),
expr("(split(Message, ','))[1]").cast("String").as("TS"),
expr("(split(Message, ','))[2]").cast("Long").as("Col3"),
expr("(split(Message, ','))[3]").cast("String").as("Col4"),
expr("(split(Message, ','))[4]").cast("String").as("Value"))
.sortWithinPartitions($"TS", $"Value")