面试官:如果让你设计一个消息中间件,如何将其网络通信性能优化10倍以上?【石杉的架构笔记】...
目錄
1、客戶端與服務端的交互
2、頻繁網絡通信帶來的性能低下問題
3、batch機制:多條消息打包成一個batch
4、request機制:多個batch打包成一個request
“ 這篇文章,給大家聊一個消息中間件相關的技術話題,對于一個優秀的消息中間件而言,客戶端與服務端通信的時候,對于這個網絡通信的機制應該如何設計,才能保證性能最優呢?甚至通過優秀的設計,讓性能提升10倍以上。
我們本文就以Kafka為例來給大家分析一下,Kafka在客戶端與服務端通信的時候,底層的一些網絡通信相關的機制如何設計以及如何進行優化的。
1、客戶端與服務端的交互
假如我們用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機器上。
整個過程,如下圖所示:
2、頻繁網絡通信帶來的性能低下問題
好了,現在問題來了,客戶端在發送消息給Kafka Broker的時候,比如說現在要發送一個訂單到Kafka上去,此時他是怎么發送過去呢?
是直接一條訂單消息就對應一個網絡請求,發送到一臺Broker上去嗎?
如果是這樣做的話,那勢必會導致頻繁的跟一臺broker進行網絡通信,頻繁的網絡通信,每次都涉及到復雜的網絡連接、傳輸的流程,那么進而會導致客戶端性能的低下。
給大家舉個例子,比如說每次通過一個網絡通信發送一條訂單到broker,需要耗時10ms。
那么如果一個訂單就一次網絡通信發送到broker,每秒最多就是發送100個訂單了,大家想想,是不是這個道理?
但是假如說你每秒有10000個訂單要發送,此時就會造成你的發送性能遠遠跟不上你的需求,也就是性能的低下,看起來你的系統發送訂單到kafka的速度就是特別的慢。
3、batch機制:多條消息打包成一個batch
所以首先針對這個問題,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中。
4、request機制:多個batch打包成一個request
事情到這里就結束了嗎?還沒有!
比如現在我們要是手頭有兩個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架構經驗傾囊相授
總結
以上是生活随笔為你收集整理的面试官:如果让你设计一个消息中间件,如何将其网络通信性能优化10倍以上?【石杉的架构笔记】...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: guns初级使用
- 下一篇: 如何搭建一个完整的手机直播系统源码?