一、客戶端與服務端的交互面試
二、頻繁網絡通訊帶來的性能低下問題網絡
三、batch機制:多條消息打包成一個batch架構
四、request機制:多個batch打包成一個request併發
「 這篇文章,給你們聊一個消息中間件相關的技術話題,對於一個優秀的消息中間件而言,客戶端與服務端通訊的時候,對於這個網絡通訊的機制應該如何設計,才能保證性能最優呢?甚至經過優秀的設計,讓性能提高10倍以上。負載均衡
咱們本文就以Kafka爲例來給你們分析一下,Kafka在客戶端與服務端通訊的時候,底層的一些網絡通訊相關的機制如何設計以及如何進行優化的。分佈式
假如咱們用kafka做爲消息中間件,勢必會有客戶端做爲生產者向他發送消息,這個你們應該均可以理解。微服務
對於Kafka來講,他自己是支持分佈式的消息存儲的,什麼意思呢?高併發
好比說如今你有一個「Topic」,一個「Topic」你就能夠理解爲一個消息數據的邏輯上的集合。性能
好比如今你要把全部的訂單數據都發送到一個「Topic」裏去,那麼這個「Topic」就叫作「OrderTopic」,裏面都放的是訂單數據。學習
接着這個「Topic」的數據可能量很大很大,不可能放在一臺機器上吧?
因此呢,咱們就能夠分散存儲在多臺Kafka的機器上,每臺機器存儲一部分的數據便可。
這就是Kafka的分佈式消息存儲的機制,每一個Kafka服務端叫作一個Broker,負責管理一臺機器上的數據。
一塊兒來看看下面的圖:
一個「Topic」能夠拆分爲多個「Partition」,每一個「Partition」存儲一部分數據,每一個Partition均可以放在不一樣的Kafka Broker機器上,這樣就實現了數據分散存儲在多臺機器上的效果了。
而後客戶端在發送消息到Kafka Broker的時候,好比說你限定了「OrderTopic」的訂單數據拆分爲3個「Partition」,那麼3個「Partition」分別放在一個Kafka Broker上,那麼也就是要把全部的訂單數據分發到三個Kafka Broker上去。
此時就會默認狀況下走一個負載均衡的策略,舉個例子,假設訂單數據一共有3萬條,就會給每一個Partition分發1萬條訂單消息,這樣訂單數據均勻分散在了3臺Broker機器上。
整個過程,以下圖所示:
好了,如今問題來了,客戶端在發送消息給Kafka Broker的時候,好比說如今要發送一個訂單到Kafka上去,此時他是怎麼發送過去呢?
是直接一條訂單消息就對應一個網絡請求,發送到一臺Broker上去嗎?
若是是這樣作的話,那勢必會致使頻繁的跟一臺broker進行網絡通訊,頻繁的網絡通訊,每次都涉及到複雜的網絡鏈接、傳輸的流程,那麼進而會致使客戶端性能的低下。
給你們舉個例子,好比說每次經過一個網絡通訊發送一條訂單到broker,須要耗時10ms。
那麼若是一個訂單就一次網絡通訊發送到broker,每秒最多就是發送100個訂單了,你們想一想,是否是這個道理?
可是假如說你每秒有10000個訂單要發送,此時就會形成你的發送性能遠遠跟不上你的需求,也就是性能的低下,看起來你的系統發送訂單到kafka的速度就是特別的慢。
因此首先針對這個問題,kafka作的第一個優化,就是實現了batch機制。
這個意思就是說,他會在客戶端放一個內存緩衝區,每次你寫一條訂單先放到內存緩衝區裏去,而後在內存緩衝區裏,會把多個訂單給打包起來成爲一個batch。
好比說默認kafka規定的batch的大小是16kb,那麼意思就是,你默認就是多條訂單湊滿16kb的大小,就會成爲一個batch,而後他就會把這個batch經過網絡通訊發送到broker上去。
假如說一個batch發送到broker,一樣也是耗費10ms而已,可是一個batch裏能夠放入100條訂單,那麼1秒是否是能夠發送100個batch?
此時,1秒是否是就能夠發送10000條訂單出去了?
並且在打包消息造成batch的時候,是有講究的,你必須是發送到同一個Topic的同一個Partition的消息,纔會進入一個batch。
這個batch裏就表明要發送到同一個Partition的多條消息,這樣後續才能經過一個網絡請求,就把這個batch發送到broker,對應寫入一個Parititon中。
事情到這裏就結束了嗎?尚未!
好比如今咱們要是手頭有兩個Topic,每一個Topic都有3個Partition,那麼每一個Broker是否是就會存放2個Partition?其中1個Partition是Topic01的,1個Partition是Topic02的。
如今假如說針對Topic01的Partition02造成了一個batch,針對Topic02的Partition02也造成了一個batch,可是這兩個batch其實都是發往同一個Broker的,如上圖的第二個Broker。
此時,仍是一個網絡請求發送一個batch過去嗎?
其實就徹底不必了,徹底此時能夠把多個發往同一個Broker的batch打包成一個request,而後一個request經過一次網絡通訊發送到 那個Broker上去。
假設一次網絡通訊仍是10ms,那麼這一次網絡通訊就發送了2個batch過去。
經過這種多個batch打包成一個request一次性發往Broker的方式,又進一步提高了網絡通訊的效率和性能。
其實 batch機制 + request 機制,都是想辦法把不少數據打包起來,而後一次網絡通訊儘可能多發送一些數據出去,這樣能夠提高單位時間內發送數據的數量。
這個單位時間內發送數據的數量,也就是所謂的「吞吐量」,也就是單位時間內能夠發送多少數據到broker上去。
好比說每秒鐘能夠發送3萬條消息過去,這就是表明了客戶端的「吞吐量」有多大。
所以,經過搞清楚這個原理,就能夠學習到這種很是優秀的設計思想。並且在面試的時候,若是跟面試官聊到kafka,也能夠跟面試官侃侃kafka底層,是如何有效的提高網絡通訊性能的。
最後再來一張圖,做爲全文總結。
一大波微服務、分佈式、高併發、高可用的原創系列文章正在路上,
歡迎關注公衆號:石杉的架構筆記
週一至週五早八點半!精品技術文章準時送上!!!
十餘年BAT架構經驗傾囊相授