初試Gevent – 高效能的Python併發框架

發表於2016-12-15

Gevent是一個基於greenlet的Python的併發框架,以微執行緒greenlet為核心,使用了epoll事件監聽機制以及諸多其他優化而變得高效。

於greenlet、eventlet相比,效能略低,但是它封裝的API非常完善,最讚的是提供了一個monkey類,可以將現有基於Python執行緒直接轉化為greenlet,相當於proxy了一下(打了patch)。

今天有空就迫不及待的試一下效果。

1、安裝

Gevent依賴libevent和greenlet,需要分別安裝。

至此,安裝完畢。

2、測試程式碼:XML-RPC

這裡必須使用支援執行緒的XML-RPC,否則無法發揮gevent的優勢!

傳統版本:
需要說明的是,這個並很多資料描述的非單執行緒,而是一個select版本,所以某些時候比執行緒版本效能好。


執行緒版本:3、測試客戶端

 4、gevent的monkey包裝後的XML-RPC

monkey是非入侵式的patch,只需要顯示呼叫你需要patch的東西就行了,別看我用了三行,其實可以patch_all()的

5、測試結果

現在只有一臺機器,下午去實驗室兩臺機器跑了以後,放上結果。對gevent還是比較寄希望的,希望不要太差。。

客戶端的特殊配置:
echo -e ‘1024t65535’ | sudo tee /proc/sys/net/ipv4/ip_local_port_range
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_syncookies
ulimit -n 10240

伺服器端的特殊配置:
echo “10152 65535″ > /proc/sys/net/ipv4/ip_local_port_range
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_tw_recycle
sysctl -w fs.file-max=128000
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.core.somaxconn=250000
sysctl -w net.ipv4.tcp_max_syn_backlog=2500
sysctl -w net.core.netdev_max_backlog=2500
ulimit -n 10240

然後說讓大家比較失望的結果:測試效果非常失敗,經常出現異常情況,根據我的分析是預設的XML-RPC沒有backlog(或者預設太低),導致壓力一大,就會fail accept,從而導致RESET(connection refused)。
所以說對monkey的patch不要抱太大希望,他是和原始碼密切相關的。

補充:已經找到修改預設backlog的方法,如下:


當然測試資料說明,不要過分迷戀monkey,那只是個傳說~

測試資料:
c=500 n=50000
預設:2845/s, 8M
多執行緒:1966/s, 51M
gevent:1888/s, 11M

c=1000 n=100000
預設:3096/s, 8M
多執行緒:1895/s, 52M
gevent:1936/s, 11M

c=5000 n=500000
預設:3009/s, 8M
多執行緒:失敗,無法建立新執行緒
gevent:1988/s, 11M

c=10000 n=1000000
預設:2883/s, 8M
多執行緒:失敗,無法建立新執行緒
gevent:1992/s, 20M

monkey的優點就是:省記憶體,我是和執行緒的相比。
我仔細的分析了一下,XML-RPC使用CPU的比例還是很大的,相比較於直接http的計算,xmlrpc還是屬於cpu密集型。
在這種CPU佔用很高,需要反覆爭奪微greenlet的情況下,gevent並不具有優勢。
或者從另一種角度說,測試機不夠強大,喂不飽gevent(可以看到,隨著併發執行緒升高,gevent的效能不降反升,而預設的則在不斷下降)

相關文章