Apache Flink动态数量的接收器

时间:2017-07-29 17:06:13

标签: apache-kafka apache-flink

我正在使用Apache Flink和KafkaConsumer从Kafka主题中读取一些值。 我也有一个从阅读文件获得的流。

根据收到的值,我想在不同的Kafka主题上编写此流。

基本上,我有一个网络,其领导者与许多孩子相关联。对于每个孩子,领导者需要在特定于孩子的Kafka主题中编写readed流,以便孩子可以阅读它。 当孩子启动时,它会在领导者所引用的kafka主题中注册。 问题是,我不知道我有多少孩子。

例如,我从Kafka主题中读到1,我想在一个名为Topic1的Kafka主题中编写流。 我读1-2我想写两个Kafka主题。 (主题1和主题2)

我不知道是否可能,因为为了在主题上写,我正在使用Kafka Producer以及AddSink方法和我的理解(以及我的试验)似乎Flink需要知道这个数字下沉的先生。

但是,那么,没有办法获得这样的行为?

2 个答案:

答案 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));
}