ウェイトレスは並行タスクをどのように処理しますか?


8

Djangoとウェイトレスを使用してpythonウェブサーバーを構築しようとしていますが、ウェイトレスが同時リクエストを処理する方法と、ブロッキングが発生する場合について知りたいのですが。


一方でウェイトレスのドキュメントは、複数のワーカースレッドが利用可能であることを言及し、それはPythonのGILは、それらを(強調私自身の)どのように影響するかを、彼らが実装されているとどのように多くの情報を提供していません。

チャネルは、クライアントが少なくとも1つの完全な有効なHTTPリクエストを送信したと判断すると、「スレッドディスパッチャー」を使用して「タスク」をスケジュールします。スレッドディスパッチャーは、クライアントの作業に使用できるワーカースレッドの固定プールを維持します(デフォルトでは4スレッド)。タスクのスケジュール時にワーカースレッドが使用可能な場合、ワーカースレッドはタスクを実行します。タスクはチャネルにアクセスでき、チャネルの出力バッファに書き戻すことができます。場合は、すべてのワーカースレッドが使用されている、スケジュールされたタスクはなりキューで待機ワーカースレッドが利用可能になるために。

Stackoverflowについてもあまり情報がないようです。「Gunicornのgthread非同期ワーカーはウェイトレスに似ていますか?」という質問から :

ウェイトレスには、リクエストをバッファリングするマスター非同期スレッドがあり、リクエストI / Oが完了すると、各リクエストを同期ワーカースレッドの1つにエンキューします。


これらのステートメントは(少なくとも私の理解から)GILに対応しておらず、誰かがウェイトレスでワーカースレッドがどのように機能するかについてさらに詳しく説明できればすばらしいと思います。ありがとう!


これに対する解決策はありましたか?
変数

@variable残念ながらそうではありません。ウェイトレスのgithub repoを簡単に見ると、彼らがGILを回避するために何かをしたようには見えませんが、確かには言えません。当面、私たちのアプリは高レベルの同時実行を必要としないため、私のチームはウェイトレスを使い続けています。
MoltenMuffins

デフォルトの開発フラスコサーバーを使用する場合、werkzeug.palletsprojects.com / en / 1.0.x / serving /…を使用してプロセス数を設定できます-これはウェイトレスに存在しませんか?
変数

はい、労働者の数を設定できますが、これは彼らのブロッキング行動については何も言いません
MoltenMuffins

ワーカーが独立したプロセスを意味する場合、これは各プロセスが独自のPythonインタープリターを持っていることを意味します。じゃない?
変数

回答:


1

以下は、イベント駆動型非同期サーバーが一般的に機能する方法です。

  • プロセスを開始し、着信要求を待機します。オペレーティングシステムのイベント通知APIを利用すると、数千のクライアントに単一のスレッド/プロセスから非常に簡単にサービスを提供できます。
  • すべての接続を管理するプロセスは1つしかないので、このプロセスで遅い(またはブロックする)タ​​スクを実行する必要はありません。それはそれがすべてのクライアントのプログラムをブロックするからです。
  • ブロックタスクを実行するために、サーバーはタスクを「ワーカー」に委任します。ワーカーは、スレッド(同じプロセスで実行中)または個別のプロセス(またはサブプロセス)になります。これで、ワーカーがブロッキングタスクを実行している間、メインプロセスはクライアントへのサービスを継続できます。

ウェイトレスは並行タスクをどのように処理しますか?

上記で説明したのとほとんど同じです。そして、ワーカーのために、プロセスではなくスレッドを作成します。

Python GILがそれらに与える影響

ウェイトレスはワーカーのスレッドを使用します。だから、はい、彼らはGILの影響を受けています。「非同期」が正しい用語です。

Pythonのスレッドは、単一のプロセス内、単一のCPUコアで実行され、並列実行されません。スレッドは非常に短い時間でGILを取得し、そのコードを実行します。その後、GILは別のスレッドによって取得されます。

ただし、GILはネットワークI / Oで解放されるため、ネットワークイベント(着信要求など)があると、親プロセスは常にGILを取得します。これにより、GILがネットワークにバインドされた操作に影響しないことを保証できます(リクエストの受信やレスポンスの送信など)。

一方、Pythonプロセスは実際には同時実行です。複数のコアで並行して実行できます。しかし、ウェイトレスはプロセスを使用しません。

あなたは心配するべきですか?

データベースの読み取り/書き込みなどの小さなブロッキングタスクを実行し、1秒あたり数百のユーザーしか処理しない場合、スレッドの使用はそれほど悪くありません。

ユーザーの大音量を提供するか、ブロックするタスクを実行している長いことについて、あなたは次のように外部のタスクキューを使用してに見ることができますセロリ。これは、プロセスを自分で生成して管理するよりもはるかに優れています。


プロセスベースのアプリサーバーを使用してより多くのリクエストを処理する方が良いですか?
変数

@variable重い計算のようなCPUにバインドされたタスク(ブロックタスクとも呼ばれます)を実行している場合、はい、プロセスワーカーを使用する方が適切です。しかし、Celeryなどのプロジェクトでは、ブロックタスクを個別の「タスクキュー」で実行するのに役立ちます。したがって、使用しているアプリサーバーの種類は関係ありません。しかし、ネットワークにバインドされたタスク(クライアント要求の待機、サードパーティのAPIからのデータのフェッチなど)を実行するためだけに、ワーカーは必要ありません。
xyres

@variableそして「プロセスベースの」サーバーとは、すべてのリクエストに対して新しいプロセスを作成するサーバーを意味するのであれば、いいえ、それは最もスケーラブルでない方法です。最も効率的な(そして一般的な)方法は、私が回答の上で説明したものです。単一のメインプロセスからすべてのリクエストを処理し、ブロッキングタスクをワーカー(スレッドまたはサブプロセス)に委任します。
xyres

「ブロッキングタスクをワーカー(スレッドまたはサブプロセス)に委任する」-セロリを意味しますか?
可変

@variable自分でプログラム内のサブプロセスのプールを維持し、それらにブロッキングタスクを渡すことができます。小規模なプロジェクトの場合、このアプローチは問題ありません。Celeryはスケーラビリティが簡単という利点があります。必要に応じて、単一のサーバーまたはサーバーのクラスターで簡単に実行できます。ただし、小規模なプロジェクトの場合、やり過ぎになる可能性があります。必要に応じて、Celeryに切り替えることができます。
xyres
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.