1. 程式人生 > >十 kafka複雜消費者

十 kafka複雜消費者

注意:對於多個partition和多個consumer

1、如果consumer比partition多,是浪費,因為kafka的設計是在一個partition上是不允許併發的,所以consumer數不要大於partition數 。
2、如果consumer比partition少,一個consumer會對應於多個partitions,這裡主要合理分配consumer數和partition數,否則會導致partition裡面的資料被取的不均勻 ,最好partiton數目是consumer數目的整數倍,所以partition數目很重要,比如取12,就很容易設定consumer數目 4
3、如果consumer從多個partition讀到資料,不保證資料間的順序性,kafka只保證在一個partition上資料是有序的,但多個partition,根據你讀的順序會有不同。
4、增減consumer,broker,partition會導致rebalance,所以rebalance後consumer對應的partition會發生變化 。


注意:資料的安全性
1、如果auto.commit.enable=true,當consumer fetch了一些資料但還沒有完全處理掉的時候,剛好到commit interval出發了提交offset操作,接著consumer crash掉了。這時已經fetch的資料還沒有處理完成但已經被commit掉,因此沒有機會再次被處理,資料丟失。
2、如果auto.commit.enable=false,假設consumer的兩個fetcher各自拿了一條資料,並且由兩個執行緒同時處理,這時執行緒t1處理完partition1的資料,手動提交offset,這裡需要著重說明的是,當手動執行commit的時候,實際上是對這個consumer程序所佔有的所有partition進行commit,kafka暫時還沒有提供更細粒度的commit方式,也就是說,即使t2沒有處理完partition2的資料,offset也被t1提交掉了。如果這時consumer crash掉,t2正在處理的這條資料就丟失了。

解決方案:
1、手動commit offset,並針對partition_num啟同樣數目的consumer程序,這樣就能保證一個consumer程序佔有一個partition,commit offset的時候不會影響別的partition的offset。但這個方法比較侷限,因為partition和consumer程序的數目必須嚴格對應。
2、另一個方法同樣需要手動commit offset,另外在consumer端再將所有fetch到的資料快取到queue裡,當把queue裡所有的資料處理完之後,再批量提交offset,這樣就能保證只有處理完的資料才被commit。