測試環境
兩台筆記本網線直連,通過測速工具(jperf)測試,確定兩台電腦之間的數據傳輸速度可以達到1Gbps,即千兆網卡的最大速度。兩台電腦硬件配置如下:
- client服務器,CPU:Intel i5-3230 2.6GHz 內存:8G
- server服務器,CPU:Intel i5-3210 2.5GHz 內存:4G
ENode使用的通信層(有興趣的可以下載ECommon的源代碼,運行代碼中的Remoting的Sample),支持Oneway, Async, Sync三種通信模式。
- Oneway表示client將數據通過socket發送后不關心server的處理結果,這種模式類似於Push-Pull的通信方式;
- Async表示client將數據發送到server后異步等待server的處理結果;
- Sync表示client將數據發送到server后同步等待server的處理結果;
由於Sync的方式效率較低,且因為ENode中使用通信層只會用到Oneway和Async兩種方式;所以我只測試了Oneway, Async這兩種通信模式。
測試結果
Oneway

說明:
- 理論上如果兩台電腦之間的帶寬是千兆,即1Gbps,即125MB的話,那假設一個消息大小是1KB,那如果發送者和接收者的CPU和內存不會成為瓶頸,那理論上每秒應該可以發送接收125 * 1024 = 128000/s。
- 關於客戶端數量是指在client機器上開幾個進程進行發送消息,目前我是一個進程一個TCP連接。
- 大家可以看到,當消息大小為1K時,客戶端機器4個進程同時發送,服務端機器全部接收完用時39.5s,也就是每秒101265接近網卡的極限。為什么沒有達到網卡的極限,其實可以到達只要我開6個進程發送消息即可。只是我上面為了方便對比,每個消息大小最多開4個進程。
- 測試過程中,我發現客戶端向服務端發送數據的吞吐量,主要的瓶頸還是在CPU。如果CPU好,那發送速度會很快,直到把網卡壓滿位置。
- 在消息大小為2K時,我沒有測試4個進程同時發送消息的場景,因為內存不夠用了。
Async

說明:
- 大家可以看到Async的通信模式,性能下降很多。是因為Async要比Oneway的方式,在邏輯上要多很多邏輯。比如發送前要先把一個TaskCompletionSource加入到一個ConcurrentDictionary中,然后當對應的RemotingRequest有回復時,獲取到對應的TaskCompletionSource,然后設置回復結果,從而讓發送數據的Task完成。以此實現異步發送數據的過程。
- 測試Async的過程中,我發現假如瞬間假如100W個TaskCompletionSource到ConcurrentDictionary,然后通過Socket進行異步發送數據,一開始CPU會壓力非常大;所以我為了降低CPU的瓶頸,讓每個客戶端只發送50W數據;
- 從上面的測試結果可以看出,1K大小的數據,Async模式發送,吞吐量最大在3.3W。經過我的分析,主要的瓶頸還是在CPU。因為此時CPU基本接近極限,而網卡只跑了250MB左右。說明我們應該盡量優化CPU的利用率,減少並發沖突。將來我准備使用Disruptor.Net來嘗試看看是否能提高Async模式的性能。
- 在消息大小在1K和2K的情況下,我沒有測試客戶端數量為4的情況,因為此時Client端機器的CPU,內存都已經成為瓶頸,沒必要測試了。實際上,在客戶端進程數量在3的時候,也已經成為瓶頸。
關於阿里雲ECS的測試計划
接下來准備再阿里雲ECS服務器上再做一下類似的測試,之前簡單摸底了一下。購買了兩台ECS虛擬機,配置都是4核8G內存。通過內網IP進行TCP測試(使用jperf工具)。發現兩台虛擬機之間,最大只能達到60MB的速度。這說明,阿里雲的ECS服務器之間,帶寬無法達到125MB,比較遺憾。但這也是我未來希望部署ENode案例的真實服務器,所以在這個環境上的測試結果,應該更具參考價值。
未來的測試計划
大概知道通信層的性能之后,我准備對EQueue發送消息和接收做性能測試。這個測試結果,就是決定ENode各個節點之間,消息傳遞吞吐量的主要依據。
