Repustate從Python遷移到Go,性能提高10倍
Repustate向世界各地的企業和組織提供文本分析服務。隨著公司的發展,他們每天處理的文本段數量從5億增加到10億,其中包括Tweet、新聞文章、博客評論、用戶反饋等。大規模的文本分析非常困難,因為很少會出現兩段文本完全相同的情況,所以無法利用緩存來提高效率。不過,它可以將大段的文本分成多個句子,然后并發分析每個句子。近日,Repustate官方博客發表了一篇博文,介紹其API的演進過程。
Repustate API的第一個版本是用Django編寫的。他們構建了一個原型,并以此為基礎推出了他們的服務。但每個Django請求/響應周期的開銷太大。隨著 API訪問量增加,可靠性問題凸顯,使用Amazon服務的成本也大大增加。于是,他們開始尋找一種Python代替方案,并選擇了Flask。Flask幾乎是現成的API,而且是輕量級的。不過,他們稍后又發現了Falcon。他們非常喜歡這個框架,因為它使用Cython進行了優化,速度比Django要快許多,而且它還遵循簡潔REST原則。事實證明,Falcon是一個很好的補救方案。Repustate的平均響應時間縮短了,故障和支持問題的數量也降下來了。
但即便如此,Repustate的性能仍然不能滿足日益增長的需求。尤其是并發,一直是Python的痛處。而且,他們用的是Python 2.7,還沒有使用Python 3中的asyncio包。但實際上,即使用了,也還是要擔心GIL的問題。并且,Falcon無法實現自托管部署。Python無法像Java或C那樣打包,然后分發。而他們的許多客戶需要在自己的網絡中運行 Repustate,他們只能為這些客戶提供一個部署了整個技術棧的虛擬應用。該虛擬應用既可以用于VMware,也可以用于Virtual Box。這是個可行的方案,但很笨重,而且更新和支持困難。所以,他們希望能夠僅僅提供一個可以安裝的二進制文件。
之所以選擇Go,是因為Go滿足了他們所有的要求:
- 比Python快
- 可以編譯成單個的二進制文件
- 可以部署到任何操作系統
- 容易實現并發
而且,Go測試套件的布局看上去比他們的nose測試要簡單。測試函數頭很容易遷移。例如,將def test_my_function():轉換成func TestMyFunction(t *testing.T) {,通過簡單的替換就可以完成。此外,go routines和channels非常易于使用,使得并發文本分析很容易實現。
整個遷移過程耗時3個月,感興趣的讀者可以查看他們的遷移過程。下面是他們的遷移成果:
- API平均響應時間由100ms降至10ms;
- 所需EC2實例的數量減少了85%;
- 由于Go可以編譯成一個單獨的二進制文件,而Go 1.5讓交叉編譯變得很容易,所以他們現在能夠提供一個Repustate自托管版本;
- 由于Python和Go相似,所以他們能夠快速重建單元測試。
另外,由于重新過了一遍Python代碼,他們還做了許多與性能無關的改進。因此,該文指出:
來自:http://www.infoq.com/cn/news/2015/09/Repustate-Python-Falcon如果時間允許,回過頭來看看舊有的代碼總是好的。你也許會驚訝,它怎么會那么差。