Apache Flink-将流等同于输入Kafka主题进行分区

问题描述

我想在Apache Flink中实现以下场景:

Scenario

鉴于Kafka主题有4个分区,我想根据事件的类型使用不同的逻辑在Flink中独立处理分区内数据。

尤其是,假设输入的Kafka主题包含先前图像中描述的事件。每个事件的结构都不同:分区1的字段为 a 作为键,分区2的字段为 b 作为键,依此类推。在Flink中,我想根据事件应用不同的业务逻辑,所以我认为我应该以某种方式拆分流。为了实现图片中描述的内容,我想只用一个消费者来做类似的事情(我不知道为什么我应该使用更多):

res

(a)是吗?另外,如果我想并行处理每个Flink分区,因为我只想按顺序处理由同一Kafka分区排序的事件,而不是全局考虑它们,(b)我该怎么做?我知道方法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(...); 的存在,但是在这种情况下我不知道在哪里应用它。

我正在寻找有关标记(a)(b)的问题的答案。预先谢谢你。

解决方法

如果可以这样构建它,它将表现得更好:

enter image description here

具体地说,我的建议是

  1. 将整个作业的并行性设置为与Kafka分区的数量完全匹配。然后,每个FlinkKafkaConsumer实例将只从一个分区读取。

  2. 如果可能,请避免使用keyBy,并避免更改并行性。然后,源,地图和接收器将全部链接在一起(这称为运算符链接),并且不需要序列化/反序列化,也不需要联网(在Flink内)。这样不仅效果良好,而且还可以利用细粒度的恢复(令人尴尬的并行流作业可以恢复一个失败的任务而不会中断其他任务)。

  3. 您可以编写通用的EventMapper,以检查正在处理的事件类型,然后执行适当的操作。或者,您可以尝试变得更聪明并实现RichMapFunction,使其在open()中找出正在处理的分区,并加载适当的映射器。