kafka消費者offset相關設置

1.自動提交offset&手動提交offset

自動提交,只需設置"enable.auto.commit",爲"true"即可,"auto.commit.interval.ms",爲默認自動提交的時間,一般設爲"1000",單位ms;
手動提交,設置"enable.auto.commit",爲"false"。手動提交有兩種形式,一種是提交所有訂閱的topic,直接在每次消費完成之後調用consumer.commitSync();另一種則是單獨提交一個topic的partition,調用形式consumer.commitSync(Collections.singletonMap(partition, new OffsetAndMetadata(lastOffset + 1)),這種形式使我們對topic可以有更加精細的控制,


2.subscribe&assign

在使用subscrible函數時,只指定了topic,不指定partition,這個時候,採用消費者組,partition會自動在這個group的所有對應consumer中分攤,會自動實現負載均衡,即rebalance。
rebalance的觸發條件有三種:
組成員發生變更(新consumer加入組、已有consumer主動離開組或已有consumer崩潰了——這兩者的區別後面會談到)
訂閱主題數發生變更——這當然是可能的,如果你使用了正則表達式的方式進行訂閱,那麼新建匹配正則表達式的topic就會觸發rebalance
訂閱主題的分區數發生變更
Rebalance的細節這裏不再討論,詳見http://www.aboutyun.com/thread-23447-1-1.html


assign函數允許你將控制粒度精確到topic中的一個確定的partition,調用方法:
     String topic = "foo";
     TopicPartition partition0 = new TopicPartition(topic, 0);
     TopicPartition partition1 = new TopicPartition(topic, 1);
     consumer.assign(Arrays.asList(partition0, partition1));


注意,subscribe和assign函數是不可以同時使用的,因爲subscribe是自動分配,並有rebalance功能,而assign則是將partition固定給consumer,因此二者不能同時使用。


3.seek(TopicPartition, long)   seekToBeginning(Collection)   seekToEnd(Collection) 

考慮這樣的情形,當你的consumer消費完數據後,在提交offset之前,系統崩潰,再次重啓,則最後一批消費的數據會被重複消費。kafka本身並不能保證"exactly once",只能保證"at-least once",
因此在有些場景下,用戶可以選擇將offset信息保存在一個安全的地方,比如說數據庫裏面,保證數據的消費和offset的提交在同一個transaction中,這樣可以保證"exactly once"。
這種場景下,除了手動提交offset外,還要用到seek函數來手動定位offset信息。
TopicPartition topicPartition1=new TopicPartition(topic,0);
consumer.assign(Arrays.asList(topicPartition1));
 consumer.seek(topicPartition1,3);


This type of usage is simplest when the partition assignment is also done manually (this would be likely in the search index use case described above). If the partition assignment is done automatically special care is needed to handle the case where partition assignments change. This can be done by providing a ConsumerRebalanceListener instance in the call to subscribe(Collection, ConsumerRebalanceListener) and subscribe(Pattern, ConsumerRebalanceListener)
在使用seek的時候需要注意,如果你是採用assign函數時,使用seek就非常簡單,因爲二者都是針對一個分區,不需要額外的設定;如果是使用subscribe的時候,則需要格外小心,因爲訂閱過程中會有分區Rebalance,需要提供一個ConsumerRebalanceListener 實例給subscribe。
如果直接使用subscribe(Collection)時,會報錯誤:
java.lang.IllegalStateException: No current assignment for partition mytopic-1
    at org.apache.kafka.clients.consumer.internals.SubscriptionState.assignedState(SubscriptionState.java:251)
    at org.apache.kafka.clients.consumer.internals.SubscriptionState.seek(SubscriptionState.java:276)
    at org.apache.kafka.clients.consumer.KafkaConsumer.seek(KafkaConsumer.java:1135)


4.從頭消費

若想從頭消費數據,則可以設置"auto.offset.reset"爲"earliest",注意要使用一個全新的group.id,即啓用一個新的消費者組,否則是不起作用的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章