kafka消費者組數量較大對性能有什麼影響?
如果消費者組的數量較大(比如幾十個group,每個組十個consumer),對消費和broker的性能有什麼影響?
感謝邀請。
坦率來說,我鼓足了很大的勇氣來到這個帖子下寫點東西。您提出的這個疑問如同「怎樣拍照才能好看?」這個經典問題一樣,讓人有一種「你若不是大牛,便別來回答」的既視感。當然,我也請你相信,我絕無冒犯的意思,只是無論如何回答,都不免讓人心生失望:「我靠,這還用你說,我當然知道這些影響,你能說點具體的嗎?」
不過我還是願意嘗試一下,姑且算是拋磚引玉了吧。
我們先說新版本consumer中每個消費組下consumer個數的影響吧。
從好的方面來說,引入多個consumer的初衷大多是為了提升消費性能,即提升消費的吞吐量。試想你的業務消費代碼打算消費100個分區的數據,使用一個consumer消費有很大可能使得各個分區的消費進度不均勻,且單個consumer單次poll回來的數據量是有限制的,最終消費端總的TPS也受限於單consumer的性能。
從不好的方面看,某個組內的consumer數越多,通常意味著該group經rebalance後達到穩定狀態的時間也就越長,因而你可能需要為max.poll.interval.ms設置更大的值。曾經也見過國外有個用戶發帖子抱怨說他的某個consumer group下有100個consumer,每次rebalance一次都要10分鐘。具體的原因就在於coordinator需要等待所有的組成員都發送JoinGroup請求後才會將group置於AwaitingSync狀態,然後等待leader成員分配方案並將方案發送給它,之後coordinator下發分配方案給各個成員。若該過程中有組成員因為各種各樣的原因導致加入組的速度過慢(比如仍然在繁重的消息處理過程中),coordinator會將已提出申請的組成員請求暫時放入purgatory中,其實就是讓大家一起等而已(當然,這個等待也是有超時限制的,不是無限等待)。那麼很顯然,組內成員數越多,rebalance過程的開銷就越有可能增大。至於group內consumer數對於broker端的影響,我個人反而覺得並不是那麼顯著。倘若某個group訂閱了10個分區且這10個分區的leader都分布在不同的broker上的話,那麼無論該group是1個consumer還是10個consumer,從broker的角度而言,客戶端都需要創建10個Socket長連接,對於broker端資源的消耗是相同的。當然了,關於group的元數據信息肯定會有差別,但內存中一個只有一個元素的Map或是List和有1000個元素的Map/List對性能的差別能有多大呢?畢竟我們不太可能創建可以產生質變效果的超大量consumer數。
下面說說consumer grouop個數對於性能的影響。其實這個方面更難評估,而且我們對於group數的確定通常都不是基於性能的,而更多可能是因業務而定。倘若業務真的需要100個group,我們不太可能為了性能而改造業務去創建更少量的group。畢竟,先要把事情做對,然後再想著把事情做得快一點。另外,每個consumer group必然需要broker端選舉一個coordinator為其服務,自然包括緩存,socket長連接等一應配套資源必然是要為其準備齊全的,這方面的性能還需要仔細評估。同時,因為每個group的位移信息都保存在__consumer_offsets的某個分區下,我們還需要考慮每個group id的散列程度,避免所有的group都分配在相同的分區下,徒增該leader broker的壓力。
好了,說了這麼多,其實最想說的是跟性能有關的問題,特別是量化性能的問題通常都是很困難的,畢竟真實環境中各種情況交織在一起,還是需要做嚴格的測試才能得出你想要的結果。
所謂大膽假設,謹慎論證,不外如是~
這種情況實踐中還是比較常見的,一般沒有什麼影響。非要說的話就是broker端的sockets數量會變多,此外需要topic partitions的數量至少等於consumers的數量,所以broker端本地文件也會更多,open file handler數量更多。
簡單補充一下 @胡夕 的答案,他寫的已經足夠完善了。
更多關於Kafka的原理分析文章,請參考答主個人技術博客 技術世界 http://www.jasongj.com/tags/Kafka/
對Broker的影響
不能只看Consumer以及Group的數量,還要看Broker和Partition的數量(這裡假設所有Group消費同一個Topic)
如果Broker有幾百個(假設為500個),Partition也是幾百個(這裡假設共500個Partition,每個Broker上各一個Partition)。這時候,你用幾十個Consumer(假設50個),與幾百個Consumer(假設500個),對於Broker來說,幾乎沒有影響。
因為Consumer對Topic的消費,是按Partition來的,每個Partition只會被一個Consumer消費,而一個Consumer可消費0個或者1個或者多個Partition,每個Consumer-Partition都意味著一個TCP連接。
所以50個Consumer與500個Consumer,對於Broker而言,沒有影響,區別只是在於是50個Consumer進程向500個Broker各發起一個連接(每個Consumer平均向10個Broker發起並維護一個連接),還是500個Consumer向幾500個Broker各發起一個連接(平均每個Consumer向1個Broker發起並維護一個連接)。所以這裡每個Broker的連接數都是一樣的,對於Broker而言消費過程也一樣,所以性能影響一樣。
當然,50個Consumer與500個Consumer,同時處理數據的速度不一樣,因此向Broker發起的請求數也不一樣。從這個角度考慮,Consumer越多,同時能處理的數據越多,能消費的數據越多,對Broker的壓力越大。但是,這點只適用於少量Consumer時數據處理速度低於數據生產速度的場景。如果數據生產速度本身比較慢,50個Consumer或者500個Consumer每秒所需處理和消費的數據與數據生產速度相同,此時50還是500個Consumer,對Broker幾乎沒有區別。
對消息性能的影響
50個Consumer與500個Consumer,並行度相差10倍。50個Consumer意味著同時有50個進程在消費數據,而500個Consumer意味著同時有500個進程在消費數據。由於Kafka Consumer使用Pull模式,能處理多少,消費多少。500個Consumer同時能處理的數據量是50個Consumer的10倍,因此能消費的數據量也是相應的10倍。
當然,這裡也是有前提的
- 下游處理沒有瓶頸,也即500個Consumer進程每秒處理的數據量確實可以達到500個Consumer進程處理的數據量的10倍。如果所有Consumer都將數據寫進同一個資料庫,並且50個Consumer的寫入速度已經達到了資料庫寫數據的瓶頸,那換成500個Consumer,同時能寫入資料庫的數據量仍然一樣,所以消費的數據量也是一樣
- 數據生產速度足夠快。如果數據生產速度比較慢,50個Consumer足以及時消費並處理完,那換500個Consumer並不會帶來消費速度的提升。
其它影響
題主沒問其它影響,答主也就不過多分析。答主 胡夕 從Rebalance的角度做了些分析。還可以從資源的利用率,Offset管理等方面作些分析
如果大到sequential read 變成了random seek,那性能會差1000倍。
推薦閱讀:
※重磅發布:Kafka迎來1.0.0版本,正式告別四位數版本號
※如何使用Kafka在生產環境構建大規模機器學習
TAG:Kafka |