apache kafka原始碼分析-Producer分析
問題導讀
1.Kafka提供了Producer類作為java producer的api,此類有幾種傳送方式?
2.總結呼叫producer.send方法包含哪些流程?
3.Producer難以理解的在什麼地方?
producer的傳送方式剖析
Kafka提供了Producer類作為java producer的api,該類有sync和async兩種傳送方式。
sync架構圖
async架構圖
呼叫流程如下:
程式碼流程如下:
Producer:當new Producer(new ProducerConfig()),其底層實現,實際會產生兩個核心類的例項:Producer、DefaultEventHandler。在建立的同時,會預設new一個ProducerPool,即我們每new一個java的Producer類,就會有建立Producer、EventHandler和ProducerPool,ProducerPool為連線不同kafka broker的池,初始連線個數有broker.list引數決定。
呼叫producer.send方法流程:
當應用程式呼叫producer.send方法時,其內部其實調的是eventhandler.handle(message)方法,eventHandler會首先序列化該訊息,
eventHandler.serialize(events)-->dispatchSerializedData()-->partitionAndCollate()-->send()-->SyncProducer.send()
呼叫邏輯解釋:當客戶端應用程式呼叫producer傳送訊息messages時(既可以傳送單條訊息,也可以傳送List多條訊息),呼叫eventhandler.serialize首先序列化所有訊息,序列化操作使用者可以自定義實現Encoder介面,下一步呼叫partitionAndCollate根據topics的messages進行分組操作,messages分配給dataPerBroker(多個不同的Broker的Map),根據不同Broker呼叫不同的SyncProducer.send批量傳送訊息資料,SyncProducer包裝了nio網路操作資訊。
Producer的sync與async傳送訊息處理,大家看以上架構圖一目瞭然。
partitionAndCollate方法詳細作用:獲取所有partitions的leader所在leaderBrokerId(就是在該partiionid的leader分佈在哪個broker上),
建立一個HashMap>>>,把messages按照brokerId分組組裝資料,然後為SyncProducer分別傳送訊息作準備工作。
名稱解釋:partKey:分割槽關鍵字,當客戶端應用程式實現Partitioner介面時,傳入引數key為分割槽關鍵字,根據key和numPartitions,返回分割槽(partitions)索引。記住partitions分割槽索引是從0開始的。
Producer平滑擴容機制
如果開發過producer客戶端程式碼,會知道metadata.broker.list引數,它的含義是kafak broker的ip和port列表,producer初始化時,就連線這幾個broker,這時大家會有疑問,producer支援kafka cluster新增broker節點?它又沒有監聽zk broker節點或從zk中獲取broker資訊,答案是肯定的,producer可以支援平滑擴容broker,他是通過定時與現有的metadata.broker.list通訊,獲取新增broker資訊,然後把新建的SyncProducer放入ProducerPool中。等待後續應用程式呼叫。
BrokerPartitionInfo的updateInfo方法程式碼如下:
ClientUtils.fetchTopicMetadata方法程式碼:
當我們啟動kafka broker後,並且大量producer和consumer時,經常會報如下異常資訊。
筆者也是經常很長時間看原始碼分析,才明白了為什麼ProducerConfig配置資訊裡面並不要求使用者提供完整的kafka叢集的broker資訊,而是任選一個或幾個即可。因為他會通過您選擇的broker和topics資訊而獲取最新的所有的broker資訊。
值得了解的是用於傳送TopicMetadataRequest的SyncProducer雖然是用ProducerPool.createSyncProducer方法建出來的,但用完並不還回ProducerPool,而是直接Close.
重難點理解:
重新整理metadata並不僅在第一次初始化時做。為了能適應kafka broker執行中因為各種原因掛掉、paritition改變等變化,
eventHandler會定期的再去重新整理一次該metadata,重新整理的間隔用引數topic.metadata.refresh.interval.ms定義,預設值是10分鐘。
這裡有三點需要強調:
客戶端呼叫send, 才會新建SyncProducer,只有呼叫send才會去定期重新整理metadata在每次取metadata時,kafka會新建一個SyncProducer去取metadata,邏輯處理完後再close。根據當前SyncProducer(一個Broker的連線)取得的最新的完整的metadata,重新整理ProducerPool中到broker的連線.每10分鐘的重新整理會直接重新把到每個broker的socket連線重建,意味著在這之後的第一個請求會有幾百毫秒的延遲。如果不想要該延遲,把topic.metadata.refresh.interval.ms值改為-1,這樣只有在傳送失敗時,才會重新重新整理。Kafka的叢集中如果某個partition所在的broker掛了,可以檢查錯誤後重啟重新加入叢集,手動做rebalance,producer的連線會再次斷掉,直到rebalance完成,那麼重新整理後取到的連線著中就會有這個新加入的broker。
說明:每個SyncProducer例項化物件會建立一個socket連線
特別注意:
在ClientUtils.fetchTopicMetadata呼叫完成後,回到BrokerPartitionInfo.updateInfo繼續執行,在其末尾,pool會根據上面取得的最新的metadata建立所有的SyncProducer,即Socket通道producerPool.updateProducer(topicsMetadata)
在ProducerPool中,SyncProducer的數目是由該topic的partition數目控制的,即每一個SyncProducer對應一個broker,內部封了一個到該broker的socket連線。每次重新整理時,會把已存在SyncProducer給close掉,即關閉socket連線,然後新建SyncProducer,即新建socket連線,去覆蓋老的。
1.Kafka提供了Producer類作為java producer的api,此類有幾種傳送方式?
2.總結呼叫producer.send方法包含哪些流程?
3.Producer難以理解的在什麼地方?
producer的傳送方式剖析
Kafka提供了Producer類作為java producer的api,該類有sync和async兩種傳送方式。
sync架構圖
async架構圖
呼叫流程如下:
程式碼流程如下:
Producer:當new Producer(new ProducerConfig()),其底層實現,實際會產生兩個核心類的例項:Producer、DefaultEventHandler。在建立的同時,會預設new一個ProducerPool,即我們每new一個java的Producer類,就會有建立Producer、EventHandler和ProducerPool,ProducerPool為連線不同kafka broker的池,初始連線個數有broker.list引數決定。
呼叫producer.send方法流程:
當應用程式呼叫producer.send方法時,其內部其實調的是eventhandler.handle(message)方法,eventHandler會首先序列化該訊息,
eventHandler.serialize(events)-->dispatchSerializedData()-->partitionAndCollate()-->send()-->SyncProducer.send()
呼叫邏輯解釋:當客戶端應用程式呼叫producer傳送訊息messages時(既可以傳送單條訊息,也可以傳送List多條訊息),呼叫eventhandler.serialize首先序列化所有訊息,序列化操作使用者可以自定義實現Encoder介面,下一步呼叫partitionAndCollate根據topics的messages進行分組操作,messages分配給dataPerBroker(多個不同的Broker的Map),根據不同Broker呼叫不同的SyncProducer.send批量傳送訊息資料,SyncProducer包裝了nio網路操作資訊。
Producer的sync與async傳送訊息處理,大家看以上架構圖一目瞭然。
partitionAndCollate方法詳細作用:獲取所有partitions的leader所在leaderBrokerId(就是在該partiionid的leader分佈在哪個broker上),
建立一個HashMap>>>,把messages按照brokerId分組組裝資料,然後為SyncProducer分別傳送訊息作準備工作。
名稱解釋:partKey:分割槽關鍵字,當客戶端應用程式實現Partitioner介面時,傳入引數key為分割槽關鍵字,根據key和numPartitions,返回分割槽(partitions)索引。記住partitions分割槽索引是從0開始的。
Producer平滑擴容機制
如果開發過producer客戶端程式碼,會知道metadata.broker.list引數,它的含義是kafak broker的ip和port列表,producer初始化時,就連線這幾個broker,這時大家會有疑問,producer支援kafka cluster新增broker節點?它又沒有監聽zk broker節點或從zk中獲取broker資訊,答案是肯定的,producer可以支援平滑擴容broker,他是通過定時與現有的metadata.broker.list通訊,獲取新增broker資訊,然後把新建的SyncProducer放入ProducerPool中。等待後續應用程式呼叫。
BrokerPartitionInfo的updateInfo方法程式碼如下:
ClientUtils.fetchTopicMetadata方法程式碼:
當我們啟動kafka broker後,並且大量producer和consumer時,經常會報如下異常資訊。
筆者也是經常很長時間看原始碼分析,才明白了為什麼ProducerConfig配置資訊裡面並不要求使用者提供完整的kafka叢集的broker資訊,而是任選一個或幾個即可。因為他會通過您選擇的broker和topics資訊而獲取最新的所有的broker資訊。
值得了解的是用於傳送TopicMetadataRequest的SyncProducer雖然是用ProducerPool.createSyncProducer方法建出來的,但用完並不還回ProducerPool,而是直接Close.
重難點理解:
重新整理metadata並不僅在第一次初始化時做。為了能適應kafka broker執行中因為各種原因掛掉、paritition改變等變化,
eventHandler會定期的再去重新整理一次該metadata,重新整理的間隔用引數topic.metadata.refresh.interval.ms定義,預設值是10分鐘。
這裡有三點需要強調:
客戶端呼叫send, 才會新建SyncProducer,只有呼叫send才會去定期重新整理metadata在每次取metadata時,kafka會新建一個SyncProducer去取metadata,邏輯處理完後再close。根據當前SyncProducer(一個Broker的連線)取得的最新的完整的metadata,重新整理ProducerPool中到broker的連線.每10分鐘的重新整理會直接重新把到每個broker的socket連線重建,意味著在這之後的第一個請求會有幾百毫秒的延遲。如果不想要該延遲,把topic.metadata.refresh.interval.ms值改為-1,這樣只有在傳送失敗時,才會重新重新整理。Kafka的叢集中如果某個partition所在的broker掛了,可以檢查錯誤後重啟重新加入叢集,手動做rebalance,producer的連線會再次斷掉,直到rebalance完成,那麼重新整理後取到的連線著中就會有這個新加入的broker。
說明:每個SyncProducer例項化物件會建立一個socket連線
特別注意:
在ClientUtils.fetchTopicMetadata呼叫完成後,回到BrokerPartitionInfo.updateInfo繼續執行,在其末尾,pool會根據上面取得的最新的metadata建立所有的SyncProducer,即Socket通道producerPool.updateProducer(topicsMetadata)
在ProducerPool中,SyncProducer的數目是由該topic的partition數目控制的,即每一個SyncProducer對應一個broker,內部封了一個到該broker的socket連線。每次重新整理時,會把已存在SyncProducer給close掉,即關閉socket連線,然後新建SyncProducer,即新建socket連線,去覆蓋老的。
如果不存在,則直接建立新的。
轉載: http://www.aboutyun.com/thread-9938-1-1.html
相關文章
- 原始碼分析Kafka之Producer原始碼Kafka
- Kafka之Producer原始碼Kafka原始碼
- apache kafka原始碼分析工程搭建(IDEA)ApacheKafka原始碼Idea
- Kafka原始碼分析Kafka原始碼
- RocketMQ中Producer的啟動原始碼分析MQ原始碼
- Kafka Java API 之Producer原始碼解析KafkaJavaAPI原始碼
- Apache HttpClient使用和原始碼分析ApacheHTTPclient原始碼
- 我花了一週讀了Kafka Producer的原始碼Kafka原始碼
- Kafka原始碼分析(二) - 生產者Kafka原始碼
- Kafka 之 async producer (2) kafka.producer.async.DefaultEventHandlerKafka
- Apache DolphinScheduler-1.3.9原始碼分析(一)Apache原始碼
- Apache DolphinScheduler-1.3.9原始碼分析(二)Apache原始碼
- Apache Kafka-0.8.1.1原始碼編譯ApacheKafka原始碼編譯
- 詳解Kafka ProducerKafka
- Apache Flink原始碼分析---JobManager啟動流程Apache原始碼
- RocketMQ基礎概念剖析,並分析一下Producer的底層原始碼MQ原始碼
- Kafka原始碼分析(三) - Server端 - 訊息儲存Kafka原始碼Server
- Retrofit原始碼分析三 原始碼分析原始碼
- alpakka-kafka(1)-producerKafka
- Kafka Producer ConsumerKafka
- Kafka 之 async producer (1)Kafka
- 集合原始碼分析[2]-AbstractList 原始碼分析原始碼
- 集合原始碼分析[1]-Collection 原始碼分析原始碼
- 集合原始碼分析[3]-ArrayList 原始碼分析原始碼
- Guava 原始碼分析之 EventBus 原始碼分析Guava原始碼
- Kafka學習(四)-------- Kafka核心之ProducerKafka
- Kafka原始碼分析(四) - Server端-請求處理框架Kafka原始碼Server框架
- Android 原始碼分析之 AsyncTask 原始碼分析Android原始碼
- 【JDK原始碼分析系列】ArrayBlockingQueue原始碼分析JDK原始碼BloC
- 以太坊原始碼分析(36)ethdb原始碼分析原始碼
- 以太坊原始碼分析(38)event原始碼分析原始碼
- 以太坊原始碼分析(41)hashimoto原始碼分析原始碼
- 以太坊原始碼分析(43)node原始碼分析原始碼
- 以太坊原始碼分析(52)trie原始碼分析原始碼
- Apache Pulsar 與 Apache Kafka 在金融場景下的效能對比分析ApacheKafka
- 從原始碼分析如何優雅的使用 Kafka 生產者原始碼Kafka
- 深度 Mybatis 3 原始碼分析(一)SqlSessionFactoryBuilder原始碼分析MyBatis原始碼SQLSessionUI
- 以太坊原始碼分析(51)rpc原始碼分析原始碼RPC