kafka-常見問題

ZeroWM發表於2017-07-30

(1)  如果想消費已經被消費過的資料

consumer是底層採用的是一個阻塞佇列,只要一有producer生產資料,那consumer就會將資料消費。當然這裡會產生一個很嚴重的問題,如果你重啟一消費者程式,那你連一條資料都抓不到,但是log檔案中明明可以看到所有資料都好好的存在。換句話說,一旦你消費過這些資料,那你就無法再次用同一個groupid消費同一組資料了。

原因:消費者消費了資料並不從佇列中移除,只是記錄了offset偏移量。同一個consumergroup的所有consumer合起來消費一個topic,並且他們每次消費的時候都會儲存一個offset引數在zookeeperroot上。如果此時某個consumer掛了或者新增一個consumer程式,將會觸發kafka的負載均衡,暫時性的重啟所有consumer,重新分配哪個consumer去消費哪個partition,然後再繼續通過儲存在zookeeper上的offset引數繼續讀取資料。注意:offset儲存的是consumer組消費的訊息偏移。 

要消費同一組資料,你可以

1 採用不同的group

2 通過一些配置,就可以將線上產生的資料同步到映象中去,然後再由特定的叢集區處理大批量的資料。

(2)  如何自定義去消費已經消費過的資料

Conosumer.properties配置檔案中有兩個重要引數

auto.commit.enable:如果為true,則consumer的消費偏移offset會被記錄到zookeeper。下次consumer啟動時會從此位置繼續消費。

auto.offset.reset  該引數只接受兩個常量largestSmallest,分別表示將當前offset指到日誌檔案的最開始位置和最近的位置。 

 如果進一步想控制時間,則需要呼叫SimpleConsumer,自己去設定相關引數。比較重要的引數是 kafka.api.OffsetRequest.EarliestTime()kafka.api.OffsetRequest.LatestTime()分別表示從日誌(資料)的開始位置讀取和只讀取最新日誌。

如何使用SimpleConsumer

首先,你必須知道讀哪個topic的哪個partition

然後,找到負責該partitionbroker leader,從而找到存有該partition副本的那個broker

再者,自己去寫requestfetch資料

最終,還要注意需要識別和處理brokerleader的改變

(3)  partitionconsumer數目關係 

1.如果consumerpartition多,是浪費,因為kafka的設計是在一個partition上是不允許併發的,所以consumer數不要大於partition數 。

    2. 如果consumerpartition少,一個consumer會對應於多個partitions,這裡主要合理分配consumer數和partition數,否則會導致partition裡面的資料被取的不均勻 。最好partiton數目是consumer數目的整數倍,所以partition數目很重要,比如取24,就很容易設定consumer數目 。

   3.如果consumer從多個partition讀到資料,不保證資料間的順序性,kafka只保證在一個partition上資料是有序的,但多個partition,根據你讀的順序會有不同 

   4. 增減consumerbrokerpartition會導致rebalance,所以rebalanceconsumer對應的partition會發生變化 

(4) topic副本問題

   Kafka儘量將所有的Partition均勻分配到整個叢集上。一個典型的部署方式是一個TopicPartition數量大於Broker的數量。

(1)  如何分配副本:

Producer在釋出訊息到某個Partition時,先通過ZooKeeper找到該PartitionLeader,然後無論該TopicReplicationFactor為多少(也即該Partition有多少個Replica),Producer只將該訊息傳送到該PartitionLeaderLeader會將該訊息寫入其本地Log。每個Follower都從Leader pull資料。這種方式上,Follower儲存的資料順序與Leader保持一致。

(2) Kafka分配Replica演算法如下:

(1)將所有Broker(假設共nBroker)和待分配的Partition排序

(2)將第iPartition分配到第(imod n)個Broker

(3)將第iPartition的第jReplica分配到第((i + j)mode n)個Broker上 

(5)  如何設定生存週期與清理資料

日誌檔案的刪除策略非常簡單:啟動一個後臺執行緒定期掃描log file列表,把儲存時間超過閥值的檔案直接刪除(根據檔案的建立時間).清理引數在server.properties檔案中: