2

私は特定の問題に遭遇し、解決策を考えました。しかし、解決策はかなり複雑なので、他の人が同様の何かに遭遇し、ベストプラクティスについてコメントしたり、代替案を提案したりできるかどうか疑問に思いました。

問題は次のとおりです。Djangoで記述されたWebアプリがあり、複数のテーブルからのデータが時間間隔で収集、グループ化、および集約される画面があります。これは基本的に、一方の軸で時間間隔で集計されたデータを、もう一方の軸で間隔ごとに集計されたデータのリソースに対して、マトリックスのような大きなエクセルです。これには、すべてのデータを収集するための多くの内部結合と左結合が含まれます。提示されたデータの「レポート」のような特性のため、rawsqlを使用してすべてを一緒にクエリします。

問題は、複数のユーザーがこれらの間隔でデータを同時に表示および編集できることです。また、同じデータを操作している他のユーザーよりも細かいまたは粗い粒度でデータを編集できますが、間隔はサブ/オーバーラップします。現在、ユーザーが一部のデータを編集すると、djangoリクエストが実行され、データが変更され、影響を受けた間隔が再び集約およびグループ化されて表示されます。しかし、このデータは不安定であるため、他のユーザーが自分の前で何かを変更した可能性があります。また、毎回テーブルをグループ化/集約および再レンダリングすることは、非常に重い操作です(データの量と間隔の範囲によって異なります)。これは、同時ユーザーが編集するとさらに悪化します。

私が提案した解決策:httpリクエスト/レスポンスメカニズムがこの種のものには本当に理想的ではないことは明らかです。グループ化/集約はかなり重いため、リクエストごとにこれを行うのは理想的ではありません。同時実行性は理想的にはユーザー間でチャネル化され、フィードバックはページ全体を更新するのではなく、googledocsのようにリアルタイムで行う必要があります。

要求に応じてdbmsから対象のフラットデータを読み取り、これをメモリにキャッシュするデーモンプロセスを作成することを考えていました。データへのすべての変更は、dbmsへのライトスルーを使用してメモリ内で発生します。このデーモンは、ロックを介してデータへのアクセスをチャネル化するため、デーモンは、他の変更を上書きできるユーザーを処理できます。

フラットデータはPythonコードを使用して集約およびグループ化され、ユーザーが必要とするスライスのみが返されます。ユーザー/デーモン通信はWebSocketを介して実行されます。デーモンはサブスクライバー/パブリッシャーチャネルを提供し、データの特定のスライスに関心のあるユーザーは、何かが変更されたときに通知されます。このデーモンは、twistedのようなフレームワークを使用して実装できます。しかし、ここでイベント駆動型のアプローチが機能するかどうかはわかりません。すべての着信要求を「チャネル化」したいからです...たぶん、これらをキューに入れて、別のスレッドで実行する必要がありますか?スケジューラーの隣のスレッドでツイスト実行する方が良いでしょうか、それともツイストメインループがこのキューで動作するスレッドをスピンオフする必要がありますか?私の理解では、スレッドはIOに最適であり、Pythonの重いコードは基本的に他のスレッドをブロックします。

誰かが以前に似たようなことをしたことがありますか?

前もって感謝します!

カール

4

2 に答える 2

3

現在廃止されているWave製品の同時編集機能のためにGoogleが実装したスキームは、http://www.waveprotocol.org/whitepapers/operational-transformに記載されています。Wave自体はすぐに放棄されましたが、Waveのこの側面は成功したように見えました。

提案されたスキームの実装についてあなたが尋ねた質問に関しては:

  1. イベント駆動型システムは、このアイデアを完全に実装できます。イベント駆動型であることは、コードを整理する方法です。特定の機能の実装を妨げることはありません。
  2. 特にPythonでは、スレッド化はあまり効果的ではありません。
    1. CPythonは(利用可能なハードウェアリソースに関係なく)一度に1つのPythonスレッドしか実行しないため、CPUバウンドの作業には重大な欠点があります。これは、マルチスレッドのCPUバウンドPythonプログラムは、通常、シングルスレッドの同等のプログラムよりも高速ではなく、さらに低速でもないことを意味します。
    2. IOの場合、IOにはCPythonでのPythonコードの実行が含まれないため、この欠点はそれほど制限されません(IO APIはすべてCで実装されます)。これは、複数のスレッドで同時にIOを実行できることを意味するため、スレッド化は潜在的にメリットがあります。ただし、単一のスレッドでIOを同時に実行することは、まさにTwistedの目的です。スレッド化は、IOを非ブロッキングで(またはおそらく非同期で)実行している限り、単一のスレッドでIOを実行するよりも利点はありません。
  3. こんにちは世界。
于 2012-08-25T13:37:11.467 に答える
2

私は似たようなことを試しましたが、あなたはその解決策に興味があるかもしれません。これが私の質問です:

TornadIO2サーバーにブロードキャストメッセージを送信するためのpythonSocket.IOクライアント

そしてこれが答えです:

https://stackoverflow.com/a/10950702/675065

彼はまた、解決策についてのブログ投稿を書きました:

http://blog.y3xz.com/blog/2012/06/08/a-modern-python-stack-for-a-real-time-web-application/

ソフトウェアスタックは次のもので構成されます。

私はこれを自分で実装しましたが、それは魅力のように機能します。

于 2012-08-25T10:51:31.287 に答える