1. 程式人生 > 實用技巧 >thrift原始碼解析——深度學習模型的伺服器端工程化落地方案

thrift原始碼解析——深度學習模型的伺服器端工程化落地方案

來源 | 極鏈AI雲(價效比最高的共享GPU算力平臺,雙十活動進行中 10.9-10.11,充值就送!最多可送2500元現金券!免費試用地址https://cloud.videojj.com/

文章來源:https://cloud.videojj.com/bbs/topic/28/thrift原始碼解析-深度學習模型的伺服器端工程化落地方案/2

有了訓練好的模型,怎麼用服務呼叫?很多人可能會想到用flask進行http呼叫。那如果是內網呢?如果希望去掉http封包解包一系列耗時操作呢?自然我們會想到rpc協議。

RPC(Remote Procedure Call)是一種遠端呼叫協議,簡單地說就是能使應用像呼叫本地方法一樣的呼叫遠端的過程或服務,可以應用在分散式服務、分散式計算、遠端服務呼叫等許多場景。有很多優秀的rpc框架,如gRpc、thrift、Dubbo、Hessian等,本文來介紹一下thrift框架中的服務模型。

為什麼需要了解服務模型?因為為了增大rpc服務端的併發處理能力,需要選擇更合適的thrift服務模型,這就需要我們瞭解各個服務模型的特性。
下面對支援python的各個服務模型做具體介紹:

一、TSimpleServer

TSimpleServer的工作模式採用最簡單的阻塞IO,實現方法簡潔明瞭,便於理解,但是一次只能接收和處理一個socket連線,效率比較低。

1、處理流程

截圖 (4).png

2、原始碼分析

截圖 (5).png

設定TServerSocket的listen()方法啟動連線監聽。
以阻塞的方式接受客戶端的連線請求,每進入一個連線即為其建立一個TSocket物件(封裝socket連線)。
為客戶端建立輸入傳輸通道物件、輸出傳輸通道物件、輸入協議物件和輸出協議物件。

processor物件為服務模型建立之前建立的,用來處理具體的業務請求。

二、TNonblockingServer TThreadPoolServer TThreadedServer

這三個服務模型放在一起講,是因為python中多執行緒有點雞肋。而這三種模型都是利用了多執行緒技術。

1、首先來看TThreadedServer,目的是為每個client請求建立單獨的執行緒進行業務處理

截圖 (6).png

2、然後是TThreadPoolServer,服務啟動時先建立好self.threads個執行緒,每個執行緒負責從佇列clients中獲取客戶端連線TSocket物件。而主執行緒負責accept客戶端的連線並建立TSocket物件,放入clients佇列。

截圖 (7).png
截圖 (8).png

3、最後是TNonblockingServer,這個稍微複雜一點。類似於java版thrift中的THsHaServer,思路是服務啟動時建立threads個執行緒負責處理task佇列中的任務訊息。而主執行緒利用io多路複用技術將準備好的可讀訊息放入task佇列供業務執行緒處理,同時在處理結束後可寫時直接將結果返回給客戶端。

截圖 (9).png
截圖 (11).png
截圖 (10).png

三、TForkingServer TProcessPoolServer

這兩個服務模型在java中並沒有發現,目的也是規避python的gil鎖問題。
其中TForkingServer,服務端每次監聽到client請求,會os.fork一個子程序進行業務處理。
截圖 (12).png

而這顯然fork會消耗一定時間,而且服務端資源不是無限的,推薦還是用下面這個,TProcessPoolServer。服務啟動時建立指定個數的程序,負責監聽同一個埠的客戶端請求,並進行業務處理。

截圖 (14).png
截圖 (13).png

以上就是主要的python版thrift服務模型介紹。需要注意的是socket.accept()從全連線佇列拿連線,連線佇列(全連線和半連線)總大小在thrfit裡預設是128,可修改

截圖 (15).png

四、實際應用:

測試環境:
64核cpu

測試結果:
無gpu操作,單次處理0.3s左右,100次請求

1、客戶端單個client序列傳送100次,或者10執行緒分別傳送10次,共享同一個client,結果均為33秒多。可見對於單個client連線伺服器處理均是序列,與程式碼顯示相符。

2、客戶端10執行緒分別傳送10次,每個執行緒建立1個client,伺服器端程序池模型(TProcessPoolServer),程序數10。用時3秒多。同樣說明對於單個client連線伺服器處理均是序列。

3、客戶端100執行緒分別傳送1次,每個執行緒建立1個client,伺服器端程序池模型(TProcessPoolServer),程序數10。用時3秒多,比測試2略多一點,可以預見服務端建立銷燬client,佔據了一點時間。

4、客戶端10執行緒分別傳送10次,每個執行緒建立1個client,伺服器端non-blocking模型(TNonblockingServer),處理執行緒數10。結果和測試1、2差不多時長,說明cpu密集型任務,python不適合多執行緒.

5、客戶端10執行緒分別傳送10次,每個執行緒建立1個client,伺服器端程序模型(TForkingServer),為每個client建立fork程序。用時4秒多。說明fork子程序耗時明顯

6、客戶端100執行緒分別傳送1次,每個執行緒建立1個client,伺服器端程序模型(TForkingServer),為每個client建立fork程序。用時11秒多,同樣說明fork子程序耗時明顯

極鏈AI雲(價效比最高的共享GPU算力平臺,雙十活動進行中 10.9-10.11,充值就送!最多可送2500元現金券!免費試用地址https://cloud.videojj.com/