Apache kafka ApacheFlink-将流作为输入Kafka主题进行同等分区
我想在Apache Flink中实现以下场景: 给定一个有4个分区的Kafka主题,我想使用不同的逻辑在Flink中独立处理分区内数据,具体取决于事件的类型 特别是,假设输入卡夫卡主题包含前面图像中描述的事件。每个事件都有不同的结构:分区1将字段“a”作为键,分区2将字段“b”作为键,等等。在Flink中,我希望根据事件应用不同的业务逻辑,因此我认为应该以某种方式拆分流。为了达到图中所描述的效果,我想只使用一个消费者(我不明白为什么我应该使用更多):Apache kafka ApacheFlink-将流作为输入Kafka主题进行同等分区,apache-kafka,parallel-processing,apache-flink,partitioning,kafka-topic,Apache Kafka,Parallel Processing,Apache Flink,Partitioning,Kafka Topic,我想在Apache Flink中实现以下场景: 给定一个有4个分区的Kafka主题,我想使用不同的逻辑在Flink中独立处理分区内数据,具体取决于事件的类型 特别是,假设输入卡夫卡主题包含前面图像中描述的事件。每个事件都有不同的结构:分区1将字段“a”作为键,分区2将字段“b”作为键,等等。在Flink中,我希望根据事件应用不同的业务逻辑,因此我认为应该以某种方式拆分流。为了达到图中所描述的效果,我想只使用一个消费者(我不明白为什么我应该使用更多): FlinkKafkaConsumer=。。
FlinkKafkaConsumer=。。。
DataStream stream=flinkEnv.addSource(消费者);
stream.keyBy(“a”).map(新的AEventMapper()).addSink(…);
stream.keyBy(“b”).map(新的BEventMapper()).addSink(…);
stream.keyBy(“c”).map(新的CEventMapper()).addSink(…);
stream.keyBy(“d”).map(新的DEventMapper()).addSink(…);
(a)正确吗?另外,如果我想并行处理每个Flink分区,因为我只想按顺序处理按同一Kafka分区排序的事件,而不全局考虑它们,(b)我该怎么做?我知道方法setParallelism()
的存在,但是我不知道在这个场景中应该在哪里应用它
我正在寻找有关标有(a)和(b)的问题的答案。提前感谢您。如果您可以这样构建它,它的性能会更好: 具体来说,我的建议是
flinkkafaconsumer
实例将从一个分区读取数据
keyBy
,并避免更改并行性。然后源、映射和接收器都将链接在一起(这称为操作符链接),不需要序列化/反序列化,也不需要联网(在Flink中)。这不仅可以很好地执行,还可以利用细粒度恢复(令人尴尬的并行流作业可以在不中断其他任务的情况下恢复一个失败的任务)
richmappfunction
,该函数在其open()
中指出正在处理哪个分区,并加载相应的映射程序
这将有助于了解管道正在做什么。为什么使用keyBys,以及事件映射程序中会发生什么?您不必这样做,但通常会将需要不同业务逻辑的不同类型的消息放到不同的主题中。分区通常用于按键分割主题和并行处理。嗨,David,谢谢你的回答。主题在同一主题上有四种不同类型的消息作为约束,我不能控制它,我只能使用它的事件;无论如何,我同意你的观点,在这种情况下,我也会提出四个不同的主题。必须以不同的方式处理每种类型的事件。例如,“a”的事件必须满足一些与“b”的事件不同的解释,因此我想将我的流划分为输入卡夫卡主题,因为每种类型的元素都必须进行不同的处理。在本例中,每个事件都可以通过一个特定的键字段进行标识,所以我想我可以通过应用keyBy来实现想要的分区,但可能是错误的方法。我想再详细说明一次,如果可能的话,我希望以并行方式处理四种不同类型的事件。非常感谢David,一如既往地清晰。嗨,David,假设数据已经以图表的形式分发,Flink还会创建每个分区的水印吗?在这种情况下,这些水印是独立的吗?我的意思是EventMapper没有多个上游输入通道,因此当FlinkKafkaConsumer进行水印时,没有“计算传入水印的最小值”的操作,然后它进行每个分区的水印。当然,如果每个使用者实例只有一个分区,那么区别就没有意义了。
FlinkKafkaConsumer<..> consumer = ...
DataStream<..> stream = flinkEnv.addSource(consumer);
stream.keyBy("a").map(new AEventMapper()).addSink(...);
stream.keyBy("b").map(new BEventMapper()).addSink(...);
stream.keyBy("c").map(new CEventMapper()).addSink(...);
stream.keyBy("d").map(new DEventMapper()).addSink(...);