blog

Thriftソースコード解析 - ディープラーニングモデルのサーバーサイドエンジニアリング着地ソリューション

ディープラーナーは、学習済みモデルがある場合、どのようにサービスを呼び出せばよいのかという疑問を持つことがよくあります。多くの人は、Http呼び出し用のFlaskを思い浮かべるかもしれません。 イント...

Jan 12, 2021 · 5 min. read
シェア



ディープラーナーは、訓練されたモデルを持っている場合、サービスとのコールをどのように行うか疑問に思うことがよくあります。多くの人はHttpコールのためにFlaskを思い浮かべるかもしれません。

イントラネットならどうでしょう?一連の時間のかかるHttpパケットとアンパケットを省きたいとしたら?当然、Rpcプロトコルが思い浮かびます。

RPCとはリモート呼び出しプロトコルのことで、簡単に言うと、ローカルメソッドを呼び出すようなアプリケーションを作ることができ、リモートプロセスやサービスを呼び出し、分散サービス、分散コンピューティング、リモートサービスの呼び出しや他の多くのシナリオに適用することができます。

gRpc、Thrift、Dubbo、Hessianなど、優れたRpcフレームワークがたくさんあります。今回は、Thriftフレームワークのサービスモデルを紹介します。

なぜサービスモデルを理解する必要があるのですか?Rpcサーバーの同時実行性を高めるためには、より適切なThriftサービスモデルを選択する必要があり、そのためには各サービスモデルの特徴を理解する必要があるからです。

Pythonをサポートする各サービスモデルを以下に説明します:

I. TSimpleServer

TSimpleServerの動作モードは、最も単純なブロッキングIOを採用し、実装方法は簡潔で理解しやすいですが、一度に1つのソケット接続しか受信して処理できないため、効率が悪くなります。

1.処理の流れ



2.ソースコード解析



TServerSocket の listen() メソッドを設定して、接続のリッスンを開始します。

クライアントからの接続要求をブロック方式で受け付け、着信接続ごとにTSocketオブジェクトを生成します。

クライアント用に、入力トランスポートチャネルオブジェクト、出力トランスポートチャネルオブジェクト、入力プロトコルオブジェクト、出力プロトコルオブジェクトを作成します。

プロセッサオブジェクトはサービスモデル用に作成され、特定のビジネスリクエストを処理するために使用されます。

II.TNonblockingServer TThreadPoolServer TThreadedServer

これらの3つのサービスモデルは、pythonのマルチスレッドというのがちょっとコケコッコーなので、一緒に語られています。そして、これら3つのモデルはすべてマルチスレッド技術を利用しています。

1、最初にTThreadedServerを見てください、目的はビジネス処理のために各クライアントリクエストに別々のスレッドを作成することです。

2、およびTThreadPoolServerは、サービス起動時に最初に良いself.threadsスレッドを作成し、各スレッドは、キュークライアントからクライアント接続TSocketオブジェクトを取得するための責任があります。メインスレッドは、クライアント接続を受け入れ、クライアントキューに配置するTSocketオブジェクトを作成する責任があります。

3、最後はTNonblockingServerですが、これは少し複雑です。THsHaServerのthriftのJavaバージョンと同様に、アイデアは、サービスの開始時にスレッドを作成することですスレッドは、タスクメッセージ内のタスクキューを処理する責任があります。メインスレッドは、io多重化技術を使って、ビジネススレッドが処理できるように、すぐに読めるメッセージをタスクキューに入れ、同時に、処理の最後に書き込めるようになったら、結果を直接クライアントに返します。



TForkingServer TProcessPoolServer

これら2つのサービスモデルはjavaにはなく、pythonのgilロックの問題を回避するためのものです。TForkingServer では、サーバがクライアントのリクエストを受け付けるたびに、子プロセスを os.fork して処理を行います。

明らかにフォークはいくつかの時間を消費し、サーバー側のリソースは無制限ではありません、クライアントの要求の同じポートをリッスンし、ビジネス処理を担当する指定された数のプロセスを作成するために、次のTProcessPoolServer.サービス起動を使用することをお勧めします。

これはpython用のthriftサービスモデルの主な紹介です。socket.accept()は完全なコネクションキューからコネクションを取得することに注意してください。

IV.実用的なアプリケーション

テスト環境:64コア

CPUテスト結果:GPU動作なし、シングル処理約0.3秒、100リクエスト

1、クライアント単一のクライアントのシリアル送信100回、または10スレッドが10回送信された、同じクライアントを共有し、結果は33秒以上です。これは、単一のクライアント接続サーバーの処理はシリアルであり、コードが一貫性を示しているために見ることができます。

2、クライアント10スレッドが10回送信され、各スレッドは、クライアントを作成するには、サーバー側のプロセスプールモデル、プロセスの数10。同じは、1つのクライアントは、サーバーの処理に接続するためにシリアルであることを示しています。

3は、クライアント100スレッドが1回送信され、各スレッドは、クライアントを作成するには、サーバー側のプロセスプールのモデルは、プロセスの数10。テスト2よりも少し多く、3秒以上かかった、それはクライアントの破壊のサーバー側の作成は、少し時間を占有することを期待することができます。

4、クライアント10スレッドが10回送信され、各スレッドは、1クライアント、サーバー側のノンブロッキングモデル、処理スレッド10の数を作成します。結果とテスト1、2ほぼ同じ時間の長さは、CPU負荷の高いタスクは、Pythonはマルチスレッドには適していないことを示しています。

5、クライアント10スレッドが10回、各スレッドは、クライアント、サーバー側のプロセスモデルを作成するには、各クライアントのフォークプロセスを作成するために送信されました。それは4秒以上かかりました。これは、フォークサブプロセスはかなりの時間がかかることを意味します。

6、クライアント100スレッドが1回、各スレッドは、クライアント、サーバー側のプロセスモデルを作成するために、各クライアントのフォークプロセスを作成するために送信されました。それは11秒以上かかり、再びフォークサブプロセスは時間がかかり、明白であることを示しています。



)



Read next

公式:同期非同期とは何か?

さて、今日の勉強の始まりです:\n\nまず、同期、非同期リクエスト\nブラウザがサーバにリクエストを送信するには、その同期リクエストと非同期リクエストの2つの方法があります。\n1同期リクエスト\n同期リクエストとはどういう意味ですか?\nそれは、リクエストを送信した後、次のリクエストを送信する前に、サーバーが返事に応答するのを待つ必要があることを意味します。

Jan 12, 2021 · 5 min read