我正在使用Apache Flink和KafkaConsumer从Kafka主题中读取一些值。 我也有一个从阅读文件获得的流。
根据收到的值,我想在不同的Kafka主题上编写此流。
基本上,我有一个网络,其领导者与许多孩子相关联。对于每个孩子,领导者需要在特定于孩子的Kafka主题中编写readed流,以便孩子可以阅读它。 当孩子启动时,它会在领导者所引用的kafka主题中注册。 问题是,我不知道我有多少孩子。
例如,我从Kafka主题中读到1,我想在一个名为Topic1的Kafka主题中编写流。 我读1-2我想写两个Kafka主题。 (主题1和主题2)
我不知道是否可能,因为为了在主题上写,我正在使用Kafka Producer以及AddSink方法和我的理解(以及我的试验)似乎Flink需要知道这个数字下沉的先生。
但是,那么,没有办法获得这样的行为?
答案 0 :(得分:1)
如果我理解你的问题,我认为你可以用一个接收器解决它,因为你可以根据正在处理的记录选择Kafka主题。它似乎也可以将来自源的一个元素写入多个主题,在这种情况下,您需要FlatMapFunction来复制每个源记录N次(每个输出主题一个),我建议输出作为一对(又名Tupple2
)与(主题,记录)。
DataStream<Tupple2<String, MyValue>> stream = input.flatMap(new FlatMapFunction<>() {
public void flatMap(MyValue value, Collector<Tupple2<String, MyValue>> out) {
for (String topic : topics) {
out.collect(Tupple2.of(topic, value));
}
}
});
然后,您可以使用先前计算的主题,通过FlinkKafkaProducer创建一个KeyedSerializationSchema来实现getTargetTopic
,以返回该对的第一个元素。
stream.addSink(new FlinkKafkaProducer10<>(
"default-topic",
new KeyedSerializationSchema<>() {
public String getTargetTopic(Tupple2<String, MyValue> element) {
return element.f0;
}
...
},
kafkaProperties)
);
答案 1 :(得分:0)
KeyedSerializationSchema 现在已弃用。相反,您必须使用“KafkaSerializationSchema”
同样可以通过覆盖序列化方法来实现。
public ProducerRecord<byte[], byte[]> serialize(
String inputString, @Nullable Long aLong){
return new ProducerRecord<>(customTopicName,
key.getBytes(StandardCharsets.UTF_8), inputString.getBytes(StandardCharsets.UTF_8));
}