Gunicornに関しては、さまざまなワーカークラスが存在することは承知していますが、この会話では、同期と非同期のタイプのみを検討しています。
私の理解から...
sync
workers = (2 * cpu) + 1
worker_class = sync
async (gevent)
workers = 1
worker_class = gevent
worker_connections = a value (lets say 2000)
(4コアシステムに基づいて)同期ワーカーを使用すると、最大9つの接続を並列処理できます。 Asyncを使用すると、最大2000個まで使用できますが、非同期に関する注意事項があります。
質問
答えてみましょう。初めに、私のデプロイメントには単一のgunicornワーカーしかいないと仮定しましょう。これにより、一度に1つのリクエストのみを処理できます。私の労働者の仕事は、google.comを呼び出して、クエリの検索結果を取得することです。次に、スループットを増やしたいと思います。以下のオプションがあります
これが最も簡単です。スレッドはプロセスよりも軽量(メモリ消費量が少ない)なので、1つのワーカーのみを保持し、それに複数のスレッドを追加します。 Gunicornは、マスターがワーカーに複数のリクエストを送信できるようにします。ワーカーはマルチスレッド化されているため、4つのリクエストを処理できます。素晴らしい。なぜ今まで以上の労働者が必要なのでしょうか?
それに答えるために、グーグルが返した検索結果でいくつかの作業を行う必要があると仮定します。たとえば、結果クエリごとに素数を計算することもできます。今、私は自分のワークロードをコンピューティングバウンドにし、Pythonのグローバルインタープリターロックの問題にぶつかりました。 4つのスレッドがありますが、実際に一度に処理できるスレッドは1つだけです。これは、複数のワーカーが必要な真の並列パフォーマンスを実現することを意味します。
したがって、これが必要なのは、真の並列処理を取得する必要がある場合です。各ワーカーは、google.comを並行して呼び出し、結果を取得し、任意の処理を実行できます。すべて並行して。素晴らしい。しかし、欠点はプロセスがより重いことであり、私のシステムは並列化を達成するために増加するワーカーの要求に追いつかないかもしれません。したがって、最良の解決策は、ワーカーを増やし、各ワーカーにスレッドを追加することです。
これ以上説明する必要はないと思います。
なぜ私はこれをしたいのでしょうか?答えるには、スレッドでさえメモリを消費することを思い出してください。スレッドを作成せずにスレッドを取得できるようにするgeventライブラリーによって実装されたコルーチン(検索可能なラジカル構造)があります。 SOワーカータイプのgeventを使用するようにgunicornを作成する場合、ワーカーでスレッドを作成する必要がないという利点が得られます。明示的に作成する必要のないスレッドを取得すると仮定します。それら。
したがって、質問に答えるために、Sync以外のworker_typeを使用している場合、gunicorn構成のスレッド数を増やす必要はありません。どうしてもできますが、それは目的をやや損ねます。
これが役に立てば幸いです。
特定の質問にも答えようとします。
いいえ、非同期ワーカークラスにはスレッドオプションはありません。これは、実際にドキュメントで明確にする必要があります。なぜそうなっていないのか疑問に思う。
これは、特定のアプリケーションの詳細な知識が必要な質問です。これらの数百の並列リクエストの処理に、DBからのフェッチ、保存、他のアプリケーションからのデータの収集などのI/O種類の操作が含まれる場合、スレッドワーカーを利用できます。ただし、そうではなく、タスクが極端に計算限界であるためにnコアCPUで実行する場合は、素数の計算など、Syncワーカーを使用する必要があります。非同期の理由は少し異なります。 Asyncを使用するには、処理がコンピューティングバウンドではないことを確認する必要があります。これは、複数のコアを使用できないことを意味します。利点は、複数のスレッドが使用するメモリがそこにないことです。ただし、モンキー以外のパッチが適用されたライブラリなど、他の問題もあります。スレッドワーカーが要件を満たしていない場合にのみ、非同期に移動します。
ライブラリ間で絶対的なスレッドセーフが必要な場合、同期、非スレッドワーカーが最適なオプションです。