標籤:

對於kafka consumer,多進程和多線程哪種更合適?


謝邀。

如果你指的是Java版本的KafkaConsumer,那麼單線程觸發"consumer.poll()"會好一些,很多具體的理由以及應用在JavaDoc裡面有很詳細的說明,這裡就直接搬運過來了:

kafka 0.10.0.1 API

可以搜索「1. One Consumer Per Thread」和「Decouple Consumption and Processing」。

如果發現哪裡寫得不夠詳細可以直接ping我,我直接修改。


謝邀。

我不太清楚你的目標是什麼,或者說你打算從哪些方面去比較Kafka Consumer在兩種使用場景下的差異。教科書中那些關於進程和線程區別的經典論述我就不贅述了,這裡只想說說我對這個問題的思考:

如果我們啟動一個Kafka消費者進程,裡面創建了多個線程同時去消費topic數據,那麼有個問題需要搞清楚:運行在這些線程中的代碼是否是線程安全的?Java並發大牛Brian Goetz已經說得很清楚了:線程安全的代碼就是要管理好共享、可變的狀態(shared and mutable state),而Kafka官網文檔中非常明確地說明了KafkaConsumer不是線程安全的。所以你的這個問題可以拆解成兩個子問題:

1. 多個單線程的consumer進程 VS. 單進程,多線程,且每個線程創建自己的KafkaConsumer

2. 多個單線程的consumer進程 VS. 單進程,多線程,所有線程共享一個KafkaConsumer

值得說明的是,我假設你提的「多進程」場景下每個進程只創建一個線程,否則情況太複雜無法進行討論。另外我假設你的consumer程序中沒有其他共享可變對象需要管理,因為這也會徒增問題的複雜度。

我們先來討論第一個子問題:多個單線程的consumer進程 VS. 單進程,多線程,且每個線程創建自己的KafkaConsumer。以我個人的觀點,它們的差異可以從以下幾個方面思考:

1. 共享進程間數據方面:多線程可以共享進程的地址空間,而多進程之間的地址空間是私有的,隔離的。但考慮到KafkaConsumer線程通常都不需要交互,它們只是獨立地運行消費任務,所以這一點幾乎沒有什麼吸引力,因為consumer實例之間不需要交互。

2. 資源使用: 差不多,這兩種使用情況在Java堆方面的開銷差異不大,因為都需要創建相同數量的KafkaConsumer實例。當然在os級別的內存開銷線程肯定要輕量級一些,但這個優勢不明顯

3 開發效率:肯定多進程簡單些,畢竟編寫正確的多線程代碼還是不太容易的
4 系統可靠性:某個線程處理代碼崩潰會使得整個進程都掛掉。多進程則沒有這樣的問題
5 擴展性:如果是單機的話多線程可能還有點優勢,畢竟你單機要是有64個cpu core,啟動64個進程的就要花一些時間。但如果我們考慮多機分散式,顯然多進程是唯一的方案。

第二個子問題:多個單線程的consumer進程 VS. 單進程,多線程,所有線程共享一個KafkaConsumer

依然從這些方面進行比較:
1. 共享進程間數據方面:此版多線程方案需要共享同一個KafkaConsumer,因此需要額外的同步開銷,在這方面不如多進程的版本
2. 資源使用: 多進程的內存開銷要明顯大於此版本的多線程開銷,特別是heap內存的佔用
3 開發效率:該版本的多線程的開發會更加複雜,因為涉及同步化訪問單個KafkaConsumer實例
4 系統可靠性:和第一個子問題一樣,多進程的方案會更好一些
5 擴展性:和第一個子問題一樣,多進程的方案會更好一些

說了這麼多,我的結論是:如果你的客戶端是單機方案,那麼使用多線程的方案會更好些,畢竟進程線程在內存中的開銷差異還未縮小到不可忽略的地步;但如果你的客戶端以後考慮多機分散式方案,那麼顯然,多進程的方案會更加適合。


推薦閱讀:

Kafka 安裝及快速入門
kafka解決了什麼問題?
Kafka設計解析(二)- Kafka High Availability (上)
Kafka Connect內部原理
kafka 0.9.0.0 __consumer_offsets日誌清理問題?

TAG:Kafka |