如何将KeyValue列表发送到Kafka?

时间:2019-05-29 08:24:00

标签: scala apache-kafka apache-kafka-streams

我正在尝试在Kafka Streams应用程序中将List [KeyValue]发送给该主题。但是流需要单个KeyValue。如何将KeyValues而不是整个列表发送到流?

my_specific_time

第二张地图因此未在编译。

class MainTopology { val createTopology = (sourceTopic: String, sinkTopic: String) => { val builder = new StreamsBuilder() builder.stream(sourceTopic) .map[String, Option[JsonMessage]]((key, value) => toJsonEvent(key, value)) .map[String, String]((key, value) => toFormattedEvents(key, value)) .to(sinkTopic) builder.build() } private val toJsonEvent = (key: String, value: String) => { println(value) val jsonEventsAsCaseClasses = jsonToClass(value) new KeyValue(key, jsonEventsAsCaseClasses) } private val toFormattedEvents = (key: String, value: Option[JsonMessage]) => { val jsonEvents: List[String] = formatEvents(value) jsonEvents.map(event => new KeyValue(key,event)) } }

我更新了代码,但现在又抛出了另一个错误:

Expression of type List[KeyValue[String, String]] doesn't conform to expected type KeyValue[_ <: String, _ <: String]
    val builder = new StreamsBuilder()
    builder.stream(sourceTopic)
      .map[String, Option[JsonMessage]]((key, value) => toJsonEvent(key, value))
      .flatMap(
      (key, value) => toFormattedEvents(key, value)
    )
      .to(sinkTopic)
    builder.build()
  }

  private val toJsonEvent = (key: String, value: String) => {
    println(value)
    val jsonEventsAsCaseClasses = jsonToClass(value)
    new KeyValue(key, jsonEventsAsCaseClasses)
  }

  private val toFormattedEvents = (key: String, value: Option[JsonMessage]) => {
    val jsonEvents: List[String] = formatEvents(value)
    jsonEvents.map(event => new KeyValue(key,event)).toIterable.asJava
  }

1 个答案:

答案 0 :(得分:1)

看看flatMap()flatMapValues()来替换第二个map()https://kafka.apache.org/22/javadoc/org/apache/kafka/streams/kstream/KStream.html

例如:

.flatMap[String, Long]((key, value) => Seq(("foo", 1L), ("bar", 2L)))

如果出于某种原因确实打算继续使用map,请参见下文。

  

第二张地图因此未在编译。

Expression of type List[KeyValue[String, String]] doesn't conform to expected type KeyValue[_ <: String, _ <: String]

相应的代码,以供参考:

.map[String, String]((key, value) => toFormattedEvents(key, value))

您需要的是类似的东西

.map[String, List[KeyValue[KR, VR]]]((key, value) => toFormattedEvents(key, value))

其中KRVR分别是toFormattedEvents()返回的键和值类型(实际的返回类型不清楚您的问题)。为此,您还必须为Serde类型使用List[KeyValue[KR, VR]]

让我用几种不同的类型来说明这一点,以便更容易理解方法调用的哪一部分涉及哪种类型。假设我们希望地图输出具有键类型Integer和值类型List[KeyValue[String, Long]]

.map[Integer, List[KeyValue[String, Long]]]((key, value) => (5, List(KeyValue.pair("foo", 1L), KeyValue.pair("bar", 2L))))

请注意,此示例为每个映射的记录分配了相同的值,但这不是示例的重点。