Flink 1.11.1 FlinkKafkaProducer写入topic0分区问题记录

Flink 1.11.1 FlinkKafkaProducer写入topic0分区问题记录

问题记录:

flink版本:1.11.1
使用FlinkKafkaProducer往下游发送数据,代码如下:

Properties props = new Properties();

            props.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"kafkatest:9092");

            FlinkKafkaProducer<String> producer = new FlinkKafkaProducer<>("partition_test_3",new SimpleStringSchema(),props);

            dataStream.flatMap(new RichFlatMapFunction<String, String>() {
                @Override
                public void flatMap(String s, Collector<String> collector) throws Exception {
                    int thisSubtask = getRuntimeContext().getIndexOfThisSubtask();
                    int parallelSubtasks = getRuntimeContext().getNumberOfParallelSubtasks();
                    System.out.println("thisSubtask:"+thisSubtask+", parallelSubtasks:"+parallelSubtasks+" value:"+s);
                    collector.collect(s);
                }
            }).addSink(producer);

上游kafkatopic有10个分区,flink开启10并行度消费topic,发现下游topic 三个partition,只有一个partition_0有数据。
10个并行度写入kafk
查看flink 1.11.1 FlinkKafkaProducer源码发现,最终创建FlinkKafkaProducer调用下图红框部分
1.11.1FlinkKafkaProducer创建其中:KafkaSerializationSchema 参数传递的是KafkaSerializationSchemaWrapper。而FlinkKakfaProducer在没有指定分区器的情况下默认使用的是
FlinkFixedPartitioner,源码如下:

public class FlinkFixedPartitioner<T> extends FlinkKafkaPartitioner<T> {

	private static final long serialVersionUID = -3785320239953858777L;

	private int parallelInstanceId;

	@Override
	public void open(int parallelInstanceId, int parallelInstances) {
		Preconditions.checkArgument(parallelInstanceId >= 0, "Id of this subtask cannot be negative.");
		Preconditions.checkArgument(parallelInstances > 0, "Number of subtasks must be larger than 0.");

		this.parallelInstanceId = parallelInstanceId;
	}

	@Override
	public int partition(T record, byte[] key, byte[] value, String targetTopic, int[] partitions) {
		Preconditions.checkArgument(
			partitions != null && partitions.length > 0,
			"Partitions of the target topic is empty.");

		return partitions[parallelInstanceId % partitions.length];
	}

	@Override
	public boolean equals(Object o) {
		return this == o || o instanceof FlinkFixedPartitioner;
	}

	@Override
	public int hashCode() {
		return FlinkFixedPartitioner.class.hashCode();
	}
}

可以看到
FlinkFixedPartitioner继承自FlinkKafkaPartitioner,并重写了open方法,其获取分区的逻辑是Flink当前的 子任务号对topic的partition数量取模(partitions[parallelInstanceId % partitions.length])
但是实际上1.11.1为什么只写到一个分区了呢?
看到FlinkKafkaPartitioner源码:
在这里插入图片描述
使用之前如果没有进行重写open方法,那么子任务号,默认就是0。
这时候返回去看 KafkaSerializationSchemaWrapper。
发现其并没有对partitioner进行open重写。
1.11.1FlinkKafkaProducer
Flink Issues:
https://issues.apache.org/jira/browse/FLINK-19285?jql=project%20%3D%20FLINK%20AND%20text%20~%20%22kafka%20partitioner%22
官方在Flink1.11.2中已修复,那来看一下1.11.2版本中的KafkaSerializationSchemaWrapper:
1.11.2
果然进行了FlinkFixedPartitioner的初始化。
1.11.2 代码测试:
上游10个分区,flink并行度10,下游topic三个分区,更换

 <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka_2.11</artifactId>
            <version>1.11.2</version>
        </dependency>

任务执行后下游三个分区均有数据写入!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值