這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
這篇完成得太折騰了,為了更好的展示benchmark的一系列結果資料,我必須得找個軟體將資料進行圖表化。以前在windows上基本都用execel畫曲線圖、柱狀圖等,但在linux/mac上卻找不到順手的工具了。我也使用過gnuplot,這貨不知道是太專業,還是太古老的原因,始終用得不順手、不開心。於是,我就決定自己先用Go和chart.js庫折騰了一個goplot工具來繪製圖表,然後再才開始寫這篇部落格。
有人可能會說我又在折騰輪子了,確實是折騰了一個輪子。話說,這又怎麼樣呢?作為一個程式員,最大的優勢就是自己用得不開心的工具,可以自己動手完善、甚至寫一個新的。我認為一個geek程式員首先就是要學會不斷的裝備自己的工具庫。不扯廢話了,迴歸正題。
測試維度
這次benchmark主要以下兩個維度進行測試
- 單個串連上,不同並發數的QPS
- 固定100個並發,不同串連數的QPS
測試過web server的人可能對這裡的並發有一點疑惑。web伺服器的並發數一般是指串連數,這裡的並發數不是指的串連數,而是同時在向伺服器發送請求的goroutine數(理解為線程數)。因為rpc的網路連接是支援並發請求的,也就是一個串連上是可以同時有很多的請求在跑,這不同於http協議一問一答的模式,而是和SPDY協議非常類似。
維度1
關注的是一個串連上能跑的請求的極限究竟是多少,這個可以用來粗略的衡量與後端的串連數。畢竟後端系統(如:DB)並不希望存在大量的串連,這和web伺服器有一點不同。這個維度更多的也是在衡量rpc的用戶端究竟能夠發送得多快。
維度2
關注的基本就是rpc伺服器的效能了,也就是看一個goroutine一個串連後,伺服器還能應付多大的並發。
測試環境
- Client和Server分別部署在兩台機器上,當然兩台機器都在同一個區域網路內,可以忽略網路。
- Client和Server的機器都是8核cpu超執行緒到16核,記憶體和網卡都遠遠足夠。
- Client每個請求只發送一個100bytes的字串給伺服器。
- GOMAXPROCS設定為16
測試結果
單串連上,不同並發數的QPS
可以看到隨著這個串連上的並發數增大,qps最後穩定在5.5W左右。這個效能有點偏低了。這一塊的效能影響主要來自鎖的開銷、序列化/還原序列化、以及goroutine的調度。一個rpc用戶端(也就是和伺服器一個串連)有一個input goroutine來負責讀取伺服器的響應,然後分發給每個寫入請求的goroutine,如果這個goroutine長時間不能被調度到,那麼就會導致寄件者的阻塞等待,Go目前的調度明顯是會有這個問題的,留到調度器再聊。
100並發,不同串連數的QPS
多個rpc用戶端可以到隨著串連數的增多,qps最後可以達到20W左右,這個時候瓶頸主要出現在cpu上了。很久以前,我用同一批機器測試avro的時候100個線程100個串連,qps在14+W。這個維度來看Go的rpc效能非常不錯。
效能應該是一個需要我們持續關注和最佳化的問題。
最後附上測試代碼: https://gist.github.com/skoo87/6510680