バックグラウンド
カフカのリバランスを見て、とても面白いと思ったので、自分で試してみました
実験計画
3つのパーティションを持つトピックを設計して、コンシューマー1、2、3、および4のタイムパーティションとコンシューマーの関係をそれぞれ確認します。
実験手順
- 3つのパーティションでトピックを作成する
//创建TopicName为topic-partition3的Topic并设置分区数为3以及副本数为1
@Bean
public NewTopic initialTopic() {
return new NewTopic("topic-partition3",3, (short) 1 );
}
复制代码
- プロデューサーは、1000ミリ秒ごとに3つのパーティションのそれぞれにデータを生成します
@Test
public void testProducer() throws InterruptedException {
for (int i = 0; i < 5000; i++) {
kafkaTemplate.send("topic-partition3", 0, null, "data package from partition0 [" + i + "]");
kafkaTemplate.send("topic-partition3", 1, null, "data package from partition1 [" + i + "]");
kafkaTemplate.send("topic-partition3", 2, null, "data package from partition2 [" + i + "]");
//休眠1秒
Thread.sleep(1000);
}
}
复制代码
- 同じ消費者グループでデータを1つずつ消費する場合、それぞれに800ミリ秒かかります
//声明consumerID为ypq-consumer, 消费组ypq-group, 为监听topicName为topic-partition3的Topic
@KafkaListener(id = "ypq-consumer", groupId = "ypq-group", topics = "topic-partition3")
public void listen(String msgData) throws InterruptedException {
LOGGER.info("consume data : " + msgData);
// 模拟耗时处理
Thread.sleep(800);
}
复制代码
- コンシューマーが1つしかない場合、C1は
ypq-group: partitions assigned: [topic-partition3-1, topic-partition3-2, topic-partition3-0]
- コンシューマーが2つある場合、C1プリント
ypq-group: partitions assigned: [topic-partition3-1, topic-partition3-0]
、C2プリントypq-group: partitions assigned: [topic-partition3-2]
- 3つの消費者、C1印刷
ypq-group: partitions assigned: [topic-partition3-0]
、C2印刷ypq-group: partitions assigned: [topic-partition3-1]
、C3印刷ypq-group: partitions assigned: [topic-partition3-2]
- コンシューマーが4つある場合、C1-3は変更されずに印刷され、C4は変更されずに印刷されます
ypq-group: partitions assigned: []
実験統計
消費者数 | P1 | P2 | P3 |
---|---|---|---|
1 | C1 | C1 | C1 |
2 | C1 | C1 | C2 |
3 | C1 | C2 | C3 |
4 | C1 | C2 | C3 |
要約する
- コンシューマーの数がパーティションの数よりも多い場合、各パーティションは最大で1つのコンシューマーしか消費できないため、アイドル状態のコンシューマーが生成されます。
- Kafkaのデフォルトのリバランス戦略は範囲であり、消費者の数に対するパーティションの数の残りは上位の消費者に割り当てられるため、上位の消費者は大きなプレッシャーにさらされています
- 同じトピックの下にある異なるパーティションのデータが正しいことを保証することはできませんが、同じパーティション内のデータが正しいことは保証されます
- 消費者がマルチスレッドを消費したい場合は、それ自体でマルチスレッド消費のデータ順序を確認する必要があります
- 消費者はまた、繰り返されるデータ消費のシナリオを考慮する必要があります