每个并发有个编号,只会读取kafka partition  % 总并发数 == 编号 的分区
 
如: 6 分区, 4个并发
分区: p0 p1 p2 p3 p4 p5
并发: 0 1 2 3 
 
分区 p0 分配给并发 0 :    0 % 4 = 0
分区 p1分配给并发1:    1 % 4 = 1
分区 p2分配给并发2:    2 % 4 = 2
分区 p3 分配给并发 3:    3 % 4 = 3
分区 p4 分配给并发 0 :    4 % 4 = 0
分区 p5 分配给并发 5 :    5 % 4 = 1
 
源码解析:
FlinkKafkaConsumerBase.java  458 行 open 方法:
public void open(Configuration configuration) throws Exception {
调用 AbstractPartitionDiscoverer 类的方法 allPartitions ,发现并分配分区:
final List<KafkaTopicPartition> allPartitions = partitionDiscoverer.discoverPartitions();
发现订阅的全部分区,并移除部分分区:
Iterator<KafkaTopicPartition> iter = newDiscoveredPartitions.iterator();
KafkaTopicPartition nextPartition;
while (iter.hasNext()) {
nextPartition = iter.next();
if (!setAndCheckDiscoveredPartition(nextPartition)) {
iter.remove();
}
}
添加还未发现的分区
public boolean setAndCheckDiscoveredPartition(KafkaTopicPartition partition) {
if (isUndiscoveredPartition(partition)) {
discoveredPartitions.add(partition);

return KafkaTopicPartitionAssigner.assign(partition, numParallelSubtasks) == indexOfThisSubtask;
}

return false;
}

public static int assign(KafkaTopicPartition partition, int numParallelSubtasks) {
int startIndex = ((partition.getTopic().hashCode() * 31) & 0x7FFFFFFF) % numParallelSubtasks;

// here, the assumption is that the id of Kafka partitions are always ascending
// starting from 0, and therefore can be used directly as the offset clockwise from the start index
return (startIndex + partition.getPartition()) % numParallelSubtasks;
}

先发现订阅的主题的所有新分区,循环所有新分区,把还未发现的新分区添加到发现的分区列表,把还未发现的新分区的
startIndex = ((partition.getTopic().hashCode() * 31) & 0x7FFFFFFF) % numParallelSubtasks;
求 startIndex(不知道干嘛), startIndex + 分区编号,对 并发数取余,
返回的结果 与 当前sub task 的并发编号相比,如果不相等,就把分区从新分区列表中移除,最后剩下的分区就是当前并发
读取的分区。
posted on 2019-04-01 15:03  Flink菜鸟  阅读(5498)  评论(0编辑  收藏  举报