[〜#〜] loc [〜#〜] プロジェクトが Django で書かれており、かなりの量の Celery ( RabbitMQ )必要に応じて非同期性とバックグラウンドジョブを実行し、システムの一部が何かで書き直されることでメリットがあるという結論に達しました Django以外の同時実行性。理由は次のとおりです。
Twisted や Tornado のようなものを使用することの長所と短所は、 Erlangなどの言語を使用する場合と比較して または Clojure ?私は実際的な利益と不利益に興味があります。
システムの一部が別の言語でうまく機能するとの結論にどうやって至ったのですか?パフォーマンスの問題がありますか?それらの問題はどの程度深刻ですか?それがより速くなる可能性がある場合、それがより速いことが不可欠ですか?
例1:Django HTTPリクエスト外での作業:
例2:Djangoシグナルを使用した「メッセージパッシング」:
post_delete
イベントが処理されます。これにより、他のオブジェクトが変更または削除される可能性があります。システムの一部が別の言語でうまく機能するという結論にどうやって至ったのですか?パフォーマンスの問題がありますか?それらの問題はどの程度深刻ですか?それがより速くなる可能性がある場合、それがより速いことが不可欠ですか?
シングルスレッドの非同期性とマルチスレッドの同時実行性の違い、長所、短所をすでに扱っているいくつかの質問やその他のWebリソースがあります。 Node.js's シングルスレッド非同期モデルがI/Oが主要なボトルネックであり、一度に多くのリクエストが処理されている場合のシングルスレッド非同期モデルの動作について読むのは興味深いです。
Twisted、Tornado、およびその他の非同期モデルは、シングルスレッドを効果的に使用しています。多くのWebプログラミングには多くのI/O(ネットワーク、データベースなど)があるため、リモート呼び出しの待機に費やされる時間は大幅に増加します。これは、他のデータベース呼び出しの開始、ページのレンダリング、データの生成など、他のことに費やす時間です。そのシングルスレッドの使用率は非常に高いです。
シングルスレッド非同期の最大の利点の1つは、使用するメモリがはるかに少ないことです。マルチスレッド実行では、各スレッドに一定量の予約済みメモリが必要です。スレッドの数が増えると、スレッドが存在するためだけに必要なメモリの量も増えます。メモリは有限なので、一度に作成できるスレッドの数に制限があることを意味します。
Webサーバーの場合、各リクエストに独自のスレッドが与えられているように見せかけます。各スレッドに1MBのメモリが必要で、Webサーバーには2GBのRAMがあるとしましょう。このWebサーバーは、これ以上処理するのに十分なメモリがなくなる前の任意の時点で(約)2000の要求を処理できます。
負荷がこれよりも大幅に高い場合、リクエストは非常に長い時間がかかります(古いリクエストが完了するのを待つとき)、または可能な同時リクエストの数を増やすために、より多くのサーバーをクラスターに投入する必要があります。 。
マルチスレッドの同時実行性は、代わりに複数のタスクを同時に実行することに依存しています。つまり、スレッドがブロックされてデータベースの呼び出しが戻るのを待機している場合、他の要求を同時に処理できます。スレッドの使用率は低くなりますが、実行されるスレッドの数ははるかに多くなります。
マルチスレッドのコードも、推論するのがはるかに困難です。ロック、同期、およびその他の楽しい同時実行性の問題があります。シングルスレッドの非同期は、同じ問題の影響を受けません。
ただし、マルチスレッドコードはCPUを集中的に使用するタスクのパフォーマンスがはるかに優れています。通常はブロックするネットワーク呼び出しなど、スレッドが「譲る」機会がない場合、単一スレッドモデルでは、同時実行性はまったくありません。
もちろん、この2つは重複しています。それらは相互に排他的ではありません。たとえば、マルチスレッドコードは、各スレッドをより適切に利用するために、非ブロッキング方法で記述できます。
他にも考慮すべき問題はたくさんありますが、私はこの2つについて次のように考えたいと思います。
特定のケースでは、完了している非同期作業の種類と、それらのタスクが発生する頻度を判別する必要があります。
簡単な答えはありません。ユースケースを検討し、それに応じて設計する必要があります。非同期のシングルスレッドモデルの方が良い場合があります。また、多数のスレッドを使用して大規模な並列処理を実現する必要がある場合もあります。
選択する同時実行モデルだけでなく、他にも検討する必要がある問題があります。 ErlangまたはClojureを知っていますか?アプリケーションのパフォーマンスを向上させるために、これらの言語のいずれかで安全なマルチスレッドコードを記述できると思いますか?これらの言語の1つに習熟するのに長い時間がかかるのでしょうか。また、学習した言語は将来的に役に立ちますか?
これら2つのシステム間の通信に関連する問題はどうですか? 2つの別々のシステムを並行して維持することは過度に複雑になるでしょうか? ErlangシステムはどのようにDjangoからタスクを受け取りますか? Erlangはこれらの結果をDjangoにどのように伝えますか?パフォーマンスは、追加された複雑さがそれに見合うほど重要な問題ですか?
私は常にDjangoで十分高速であることがわかりました。非常にトラフィックの多いサイトで使用されています。同時要求の数と応答時間を増やすために実行できるいくつかのパフォーマンス最適化があります。確かに、これまでCeleryで何もしていないので、通常のパフォーマンスの最適化では、これらの非同期タスクで発生する可能性のある問題はおそらく解決されません。
もちろん、問題により多くのハードウェアを投入するという提案は常にあります。新しいサーバーのプロビジョニングのコストは、まったく新しいサブシステムの開発および保守のコストよりも安いですか。
この時点であまりにも多くの質問をしましたが、それは私の意図でした。答えは、分析と詳細がなければ簡単ではありません。問題を分析できるということは、質問することを知ることにもなりますが、うまくいけば、私はその面で助けてくれました。
私の直感は、別の言語での書き換えは不要だと言っています。複雑さとコストはおそらく大きすぎるでしょう。
編集
フォローアップでは、いくつかの非常に興味深い使用例を紹介しています。
最初の例では、NFC=タグを読み取ってから、データベースにクエリを実行しました。別の言語でこの部分を書くことは、データベースまたはLDAPサーバーにクエリを実行するという理由だけで、それほど役に立ちません。はネットワークI/O(および場合によってはデータベースのパフォーマンス)によってバインドされます。一方、各管理コマンドは独自のプロセスとして実行されるため、同時リクエストの数はサーバー自体によってバインドされます。既に実行中のプロセスにメッセージを送信していないため、パフォーマンスに影響するセットアップ時間とティアダウン時間。ただし、それぞれが独立したプロセスになるため、同時に複数の要求を送信できます。
この場合、私はあなたが調査できる2つの道を見ます:
'OPTIONS': {'threaded':True}
を構成する必要があります。)データベースレベルまたはDjango level独自のデータベースを微調整できることを確認します。データベースクエリを記述する言語に関係なく、LEDを点灯させるには、このデータが返されるのを待つ必要があります。クエリコードのパフォーマンスcanでも違いがあります。Django ORMは高速ではありません(but、通常は十分高速です)。DjangoにどのWebサーバーを使用しているかわかりません。 Apacheのmod_wsgi
を使用すると、リクエストを処理するプロセス内のプロセスとスレッドの数を設定できます。サービス可能なリクエストの数を最適化するために、必ずWebサーバーの関連する構成を微調整してください。
2番目の使用例もかなり興味深いものです。その答えがあるかどうかわかりません。モデルインスタンスを削除していて、後でそれらを操作したい場合、JSON.dumps
をシリアル化してからJSON.loads
を逆シリアル化できる可能性があります。関連フィールドはデータベースから遅延ロードされ、そのリンクは存在しなくなるため、後で(関連モデルのクエリ)オブジェクトグラフを完全に再作成することはできません。
他のオプションは、何らかの方法でオブジェクトを削除するためにmarkし、要求/応答サイクルの最後にのみ(すべてのシグナルが処理された後)削除することです。これを実装するには、post_delete
に依存するのではなく、カスタム信号が必要になる場合があります。
私は主要な米国 [〜#〜] isp [〜#〜] に対して非常に高度でスケーラブルな開発を行いました。 Twisted サーバーを使用していくつかの深刻なトランザクション数を実行しました。Python/ CPUバインド =。 I/Oバウンド は問題ではありませんが、CPUバウンドは不可能でした。システムをすばやく組み立てることはできましたが、数百万の同時ユーザーに拡張できるようにすることは、CPUに拘束される場合、構成と複雑さの悪夢でした。
私はそれについてブログ投稿を書きました、Python/Twisted VS Erlang/OTP。
TLDR; Erlang ウォン。
Twisted の実用的な問題(これは私が大好きで、約5年間使用しています):
Node.jsで CoffeeScript を使用して少し作業を行いましたが、同時実行パフォーマンスが懸念される場合は、飛躍的に価値があるかもしれません。
Django の複数のインスタンスを実行することを検討しましたか?
別の言語への切り替えを検討する前に、次のことをお勧めします。
select
)。これはI/Oに適しています。Pythonアプリケーションでパフォーマンスが優先されると、スレッドを使用しません。上記のオプションを使用すると、ソフトウェアの再利用や Django との接続など、多くの問題を解決できます、パフォーマンス、開発のしやすさなど.