gRPC完了キューアーキテクチャ
- grpcはcompletion_queueを使用して、通常はrpcリクエストのようなイベントをキャッシュします。
- イベントをcqに追加するにはgrpc_cq_end_opを使用し、キューからイベントを取得するにはgrpc_completion_queue_nextまたはpluckを使用します。
- next / pluckの違いは、nextは順番にキューからイベントを取得し、pluckはタグ条件を指定することで特定のイベントを取得できることです。
次に、同期RPC要求のプロセスフローを通じてcompletion_queueの特定の使用法を理解します。
- grpc_serverの場合、指定された数のcqが、起動時の構成に従ってRPC要求を処理するために使用されます。デフォルトは1です。
- 各cqに対して、ThreadManager(スレッドプール)の処理が開始されます。これは、1〜CPUコアスレッドを使用してepoll要求を処理し、次に他の動的スレッドを使用して特定のRPCメソッドを処理します。
- grpc_serverに登録されているRPCメソッドごとに、register_methodで管理されます。各register_methodには、受信したRPC要求を追跡するためのrequest_matcherがあります。
request_matcherは、RPC要求を次のように追跡します。
- 内部で固定数のトークンを維持します(トークンの数はcqの数と同じです)。要求が到着したときにトークンがある場合は、それをcqキューに入れるように指定します。トークンが現在消費されている場合は、キューに入れられて処理されます(要求は保留状態です)。
- grpc_serverは、RPCリクエストを受信するたびにトークンを適用します。RPCメソッドを実際に処理するときに、トークンを返し、同時に処理される保留中のステータスリクエストがあるかどうかを判断します。
- このメカニズムにより、RPC要求に対して特定のフロー制御が実行されます。
上記のさまざまなオブジェクトの関係を以下に示します。
RPCリクエストが到着したときにキューを使用する方法を見てみましょう。
オブジェクトに関する全体的な関係は次のとおりです。
CQは通常3つの部分で構成されます
- grpc_completion_queue構造ヘッダーは、キュー管理情報を格納するために使用されます。
- completion_queue_data、キューデータストレージ。grpc_cq_event_queueを介して内部的にイベントを格納します。このキューはMPSC(マルチプロデューサーシングルコンシューマーキュー)であり、コンシューマーが1つしかない場合はロックがなく、高いパフォーマンスを発揮します。複数のコンシューマーがある場合、ロックは同期に使用されます
- grpc_pollsetは、関連するfdを管理するために使用され、イベントループを駆動します。
RPCリクエストが到着すると、grpc_cq_end_opはRPCリクエストをカプセル化してgrpc_cq_completionに入れます。それがキューの最初のイベントである場合は、grpc_pollsetのキックを呼び出してワーカーを起動し、タスクを完了させます。