如何按顺序从Apache Spark发送消息到Kafka主题

时间:2017-08-30 14:23:25

标签: hadoop apache-spark apache-kafka spark-dataframe kafka-producer-api

我有一个用例,在MySQL中连续插入有关传感器的事件信息。我们需要每隔1或2分钟在Kafka主题中通过一些处理发送此信息。

我正在使用Spark将此信息发送到Kafka主题并在Phoenix表中维护CDC。我正在使用Cron作业每1分钟运行一次火花作业。

我目前面临的问题是消息排序,我需要在升序时间戳中发送这些消息以结束系统Kafka主题(它有1个分区)。但是由于多个spark DataFrame分区同时向Kafka主题发送信息,大多数消息排序都会丢失。

目前作为一种解决方法,我将我的DataFrame重新分区为1,以便维护消息排序,但这不是一个长期的解决方案,因为我正在失去火花分布式计算。

如果你们有更好的解决方案设计,请建议。

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")