前兩章講述比較重要的一個特性就是Kafka 的消費位移 其中包含 位移的含義,位移的發展史 和位移的提交方式。本文接下來繼續講述另外一個特性那就是消費組。
分組消費時Kafka 一個比較具有亮點的一個特性,那什麼時消費組呢 大概就是:Kafka 提供的可擴展且具有容錯性的消費者機制。那麼這裏既然提到了組的概念。此時你可能想到這個是一個多個消費者的集合。沒錯答案就是這樣子的。多個消費者共用一個Group Id 構成一個消費組,組內的消費者一起來訂閱主題的所有分區當然一個消費者實例只會消費一個分區。
那麼爲什麼要設計這個消費組呢。在傳統的消息隊列中消息一旦被消費,可能直接就刪除了,而且一個只能被一個消費者進行消費。如果想要重新消費或者想要多個消費者消費同一個數據實現起來非常麻煩。而且這種設計十分的不靈活。也會影響數據的真實投遞性。如果有這樣一個設計 消費組之間各個消費者互相獨立,互不影響,能夠訂閱相同的一組主題又互補干涉。那真是太棒了。
Kafka 僅僅使用Consumer Group 這一種機制,卻同時實現了傳統消息引擎系統的兩大模型:如果所有實例都屬於同一個 Group,那麼它實現的就是消息隊列模型;如果所有實例分別屬於不同的 Group,那麼它實現的就是發佈 / 訂閱模型。
這一個消費組中, 理想的情況下消費組的消費者個數和所要消費的分區數是相等的。但是在現實場景中可能會出現一個消費者會出現消費多個分區而又部分消費者沒有消費任何分區靜靜悄悄的在哪裏躺着。爲什麼舉個例子, 假設我們又6個分區但是有8個消費者那麼就會有兩個消費者躺在哪裏,要是不發生重平衡的話它兩可能一趟就是一輩子。至於什麼是重平衡下一篇介紹。那爲什麼又會有一個消費者消費多個呢假設原先有六個分區,爲了避免上述的資源浪費的情況只設置了6個消費者。但是此時有一個消費者掛了那麼會發生重平衡此時必然有一個消費者需要消費多個。
那麼講了這麼多那麼怎麼使用呢只需要配置group.id
就好了
public static void main(String[] args) {
Map map=new HashMap<String,String>();
map.put("bootstrap.servers","localhost:9092");
map.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
map.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
map.put("group.id","test1");
KafkaConsumer kafkaConsumer=new KafkaConsumer(map);
kafkaConsumer.subscribe(Arrays.asList("test-topic"));
while (true){
ConsumerRecords<String, String> consumerRecords= kafkaConsumer.poll(Duration.ofMillis(1000));
if(consumerRecords !=null){
Iterator<ConsumerRecord<String,String>> ite= consumerRecords.iterator();
while (ite.hasNext()){
System.out.println(ite.next().value());
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}