C++網絡通信庫性能大比拼
C/C++網絡通信庫有不少,本次benchmark的目的是為了公平的評估它們的網絡I/O性能,當然是作為REST server, 因此每個server都寫了一些代碼,好在不是特別復雜。這個測試經過了好幾輪,本文給出了最終的結論。
先上結論,大家都忙:)
候選者:cppcms, boost asio, libevent, muduo和 nginx,nginx不是庫,這裡做測試使用它作為基准,畢竟很多人心裡,它是不可挑戰的。
結論:QPS的比拼結果,cppcms最弱,boost asio好很多,libevent好更多,nginx比libevent還要好點,muduo最好。
但是,不要小瞧這裡最弱的cppcms,它仍可以輕易擊敗php, ruby, java, go, python, nodejs等語言編寫的rest server。
下面介紹測試的方法
測試工具:wrk
之前選用過apache的ab test工具,不要被名字騙了,和常說的ab test方法沒什麼關系。這是一個壓力測試工具,但是明顯不能將壓力升到最高,還是wrk效果最好。因為壓測的目標是,擊穿服務器,然後減少點壓力,找到能夠讓服務器網絡程序正常工作的最大壓力。
找測試工具的唯一標准就是能不能用足壓測客戶機器的資源,釋放最大的壓力。其他非C/C++的壓測工具也就直接謝絕了,這不是什麼開發效率至上的場合。
wrk -t4 -c200 -d60s http://167serverip:serverport/collect?v=1
wrk tool; 4 threads; 200 concurrency connection; duration 60s.
測試服務器
Table 1: benchmark env
Machine |
CPU Model |
MEM |
NETCARD(Gbps) |
OS |
client
Intel(R) Xeon(R) CPU E5620 @2.40GHz 8 core
16G
1
CentOS release 6.5 (Final) x86_64
server
Intel(R) Xeon(R) CPU E5620 @2.40GHz 8 core
16G
1
CentOS release 6.5 (Final) x86_64
8核服務器,CentOS系統是樂視大運維同事優化過內核的,性能應該超過下載下來的默認系統。測試服務器分成兩種,client負責發出http調用,server負責接受http請求,我們測量的就是server成功處理的最大QPS.
網絡程序架構
都使用epoll,不過還是有差別,主要在多線程模型上。
Table 2: server architecture
Server |
Process Num |
Thread Num |
IO Pattern |
cppcms_based
1
default threads = core*5
epoll one thread io_loop
asio_based
1
8
epoll io_loop-per-thread
muduo_based
1
8
epoll io_loop-per-thread
libevent_based
1
8
epoll io_loop-per-thread
nginx
8 worker
1
epoll one thread io_loop
測試結果
format: min/max/average
Table 3: benchmark result
Server |
Cpu |
Mem |
Disk |
Netcard(in/out) |
Requests/sec |
libevent_based
684% / 768% / 756%
7276 / 9.9M / 8231
-
-
104797 / 112025 / 111998
asio_based
302% / 357% / 309%
5522 / 5976 / 5743
-
-
18971 / 19246 / 19163
cppcms_based
230% / 249% / 231%
9210 / 9428 / 9378
-
-
15434 / 16391 / 15500
muduo_based
680% / 754% / 702%
6644 / 7332 / 6720
-
-
286586 / 289423 / 287332
nginx
8*80% / 8*86 / 8*82
8*44M / 8*44M / 8*44M
-
-
112658 / 114127 / 113406
如果使用O3優化選項, 發現對於boost asio和muduo有較大提升。
Table 5: more details httpserver all versions benchmark
Server |
Compiler |
Optimization option |
Cpu |
Mem |
Disk |
Netcard(in/out) |
Requests/sec |
cppcms_based
clang++ 3.6.2
-O3
228% / 239% / 228%
9356 / 9416 / 9416
-
-
14252 / 16124 / 15820
asio_based
clang++ 3.6.2
-O3
300% / 305% / 303%
4368 / 4564 /4416
-
-
33069 / 34247 / 33360
libevent_based
clang++ 3.6.2
-O3
763% / 764% / 764%
5560 / 10M / 5520
-
-
113373 / 114072 / 113713
muduo_based
clang++ 3.6.2
-O3
650% / 694% / 658%
6272 / 6324 / 6312
-
-
303202 / 307204 / 305839
其他測試結論
我們使用的是clang++編譯器和g++編譯器,優化選項是O3, 發現兩個編譯器編譯出來的程序性能相當。
我們做了C++11和之前的C++03版本的對比,發現C++11略好於C++03。
還有很多輪測試,限於篇幅,不在這裡描述。
為什麼cppcms和boost asio性能不高?
因為mutex,對epoll使用最高效的方式在多線程裡面每個線程都調用epoll_wait,而這兩個庫都增加了mutex去鎖,導致性能低下。
mudoo性能特別高的原因是它的設計只考慮linux平台,只把一個平台的通信庫做到極致,設計目的單純,因此能夠做到最好。
具體的原因後面會專門發表文章剖析。今天先寫這麼多。