12

私はasp.net-mvcWebサイトを持っており、人々はプロジェクトのリストを管理しています。いくつかのアルゴリズムに基づいて、プロジェクトが古くなっているかどうかを知ることができます。ユーザーがログインするときに、古いプロジェクトの数を表示したい(受信トレイに更新の数が表示される場合と同様)。

古いプロジェクトを計算するアルゴリズムは少し遅いので、ユーザーがログインするたびに、次のことを行う必要があります。

  1. 所有者であるすべてのプロジェクトに対してクエリを実行します
  2. IsStale()アルゴリズムを実行します
  3. IsStale=trueのカウントを表示します

私の推測では、それは本当に遅いでしょう。また、すべてのプロジェクトの書き込みで、変更されたかどうかを確認するために上記を再計算する必要があります。

私が持っていたもう1つのアイデアは、テーブルを作成し、すべての分でジョブを実行して、古いプロジェクトを計算し、このメトリックテーブルに最新のカウントを保存することでした。次に、ユーザーがログインしたときにクエリを実行します。問題は、そのテーブルの同期を維持する必要があることです。再計算が1分に1回だけの場合、プロジェクトを更新すると、1分後まで値が変更されません。

レビューするアイテムの数をユーザーに警告するために、この受信トレイの概念をサポートするための高速でスケーラブルな方法のアイデアはありますか?

4

5 に答える 5

10

最初のステップは、常に適切な要件分析です。私がプロジェクトマネージャーだとしましょう。システムにログインすると、唯一のプロジェクトが時間どおりに表示されます。開発者が私のオフィスに来て、彼の活動に遅れがあると私に言いました。開発者のアクティビティを選択し、その期間を変更します。システムはまだ私のプロジェクトを時間通りに表示しているので、私は喜んで仕事を辞めます。

午前3時にクライアントから電話があり、プロジェクトが時間どおりに行われなくなった理由の説明を求められたら、どのように感じますか?明らかに、システムが私に警告を出さなかったので、非常に驚​​いています。なぜそれが起こったのですか?プロジェクトのステータスを更新するために、スケジュールされたジョブの次の実行を30秒(なぜ1秒だけではないのですか?)待たなければならなかったためです。

それは解決策にはなり得ません。プロセスの実行に30秒かかる場合でも、警告をユーザーにすぐに送信する必要がありIsStale()ます。ユーザーにloading...画像などを表示しますが、ユーザーが正確なデータを持っていることを確認してください。

さて、実装に関しては、前の問題から逃げるために何もすることはできません。いくつかの期日に影響を与える何かが変更されたときに、そのプロセスを実行する必要があります。ただし、できることは、そのプロセスを不必要に実行することではありません。たとえば、ユーザーがログインするたびに実行できるとおっしゃいました。2人以上のユーザーがログインして同じプロジェクトを表示し、何も変更しない場合はどうなりますか?プロセスを2回実行する必要はありません。

さらに、ユーザーがプロジェクトを更新するときにプロセスが実行されていることを確認すれば、それ以外のときにプロセスを実行する必要はありません。結論として、このスキーマには、「ポーリング」ソリューションと比較して次の長所と短所があります。

利点

  • 予定されている仕事はありません
  • dirty不要なプロセスは実行されません(プロジェクトにフラグを設定し、フラグが設定されている場合にのみ実行できるため、これは議論の余地がありますtrue
  • dirty値の不要なクエリはありません
  • ユーザーには、プロジェクトの現在お​​よび実際の状態が常に通知されます(これは、提供されているソリューションで対処する最も重要な項目です)。

短所

  • ユーザーがプロジェクトを更新し、数秒で再度更新した場合、プロセスは2回実行されます(ポーリングスキーマでは、スケジュールされた頻度によっては、プロセスがその期間に1回実行されない場合もあります)。
  • プロジェクトを更新するユーザーは、プロセスが終了するのを待つ必要があります

StackOverflowと同様の方法で通知システムを実装する方法に変更すると、まったく別の質問になります。あなたはユーザーやプロジェクトと多対多の関係を持っていると思います。最も簡単な解決策は、これらのエンティティ間の関係に単一の属性を追加することです(中央のテーブル)。

カーディナリティ:ユーザーには多くのプロジェクトがあります。プロジェクトには多くのユーザーがいます

そうすれば、プロセスを実行するときに、各ユーザーHas_pending_notificationsを新しい結果で更新する必要があります。たとえば、ユーザーがプロジェクトを更新し、それが時間どおりに行われtrueなくなった場合は、すべてのユーザーフィールドに設定して、ユーザーHas_pending_notificationsが状況を認識できるようにする必要があります。同様に、プロジェクトが時間どおりになっているときに設定しますfalse(プロジェクトが時間どおりになっていないときに通知が表示されることを確認したいだけだと思います)。

StackOverflowの例をとると、ユーザーが通知を読むときは、フラグをに設定する必要がありますfalse。タイムスタンプを使用して、ユーザーが通知を読んだかどうかを推測しないようにしてください。ログインしても、通知を読んだわけではありません。

最後に、通知自体が十分に複雑な場合は、ユーザーとプロジェクトの関係から通知を移動して、次のようにすることができます。

カーディナリティ:ユーザーには多くのプロジェクトがあります。プロジェクトには多くのユーザーがいます。ユーザーには多くの通知があります。通知には1人のユーザーがいます。プロジェクトには多くの通知があります。通知には1つのプロジェクトがあります。

私が言ったことが理にかなっていることを願っています、またはあなたに他のより良いアイデアを与えるでしょう:)

于 2012-03-15T22:58:59.710 に答える
6

次のように実行できます。

  1. 各ユーザーレコードに、遅い計算が最後に実行された時刻を示す日時フィールドを追加します。それをLastDateと呼びます。
  2. 各プロジェクトにブール値を追加して、リストする必要があるかどうかを示します。それを呼び出す:選択
  3. Slowプロシージャセットを実行すると、選択したファイルが更新されます
  4. これで、 LastDateが今に十分近い場合にユーザーがログに記録すると、最後の遅い計算の結果を使用して、 Selectedtrueですべてのプロジェクトを取得します。それ以外の場合は、計算が遅くなります。上記の手順は最適です。一定の時間間隔で手順を実行しながら、実際に必要な場合にのみ遅い手順を再計算するためです...おそらくユーザーが計算の結果を使用する可能性があるため、時間を無駄にするリスクがあります。
于 2012-03-14T19:46:32.670 に答える
3

フィールドを「古く」します。stale = 0 AND(そのアルゴリズムはtrueを返す)であるすべてのレコードでstale=1を更新するSQLステートメントを実行します。次に、stale=1であるすべてのレコードを選択するSQLステートメントを実行します。

これが高速に機能する理由は、PHPなどのSQLパーサーが、前半がtrueを返した場合、ANDステートメントの後半を実行してはならないためです。これにより、リスト全体が非常に高速に実行され、すべてのレコードがチェックされ、まだ古くなっていない場合は、古くします。すでに古くなっている場合、アルゴリズムは実行されないため、時間を節約できます。そうでない場合は、アルゴリズムが実行されて古くなったかどうかが確認され、古くなったものが1に設定されます。

次に、2番目のクエリは、stale=1であるすべての古いレコードを返します。

于 2012-03-12T04:48:03.767 に答える
0

あなたはこれを行うことができます:

データベースでは、ユーザーがプロジェクトにアクセスするたびにタイムスタンプを変更します。ユーザーがログインしたら、すべてのプロジェクトをプルします。タイムスタンプを確認し、今日の日付と比較します。n日より古い場合は、古いリストに追加します。日付を比較するとロジックが遅くなるとは思いません。

于 2012-03-12T04:48:10.970 に答える
0

データベースとコードについて考える前に、基本的な質問を解決する必要があると思います。これらの主なものは次のとおりです。「IsStale()が遅いのはなぜですか?」

他の場所のコメントから、これが遅いという概念は交渉の余地がないことは明らかです。この計算はあなたの手の届かないところにありますか?結果はキャッシングに対して耐性がありますか?どのレベルの変更が再計算をトリガーしますか。

過去にスケジューリングシステムを作成したことがあるので、変更には2つのタイプがあります。1つはスラック内で発生する可能性があるもの、もう1つはカスケードスケジュール変更を引き起こすものです。同様に、再構築には、合計とローカルの2つのタイプがあります。完全な再構築は明らかです。ローカル再構築は、他のスケジュールされたリソースへの「損傷」を最小限に抑えようとします。

問題の核心は次のとおりです。更新のたびに完全に再構築する場合、変更からスケジュールが安定するまでの30分の遅れを確認できます。(これは、非常に複雑なワークロードでのERPシステムの再構築時間の経験に基づいています)。

システムの現実がそのようなタスクに30分かかるということである場合、ユーザーに即座に満足させるという設計目標を持つことは、問題の真実に反します。ただし、再構築よりもはるかに高速にスケジュールの不整合を検出できる場合があります。その場合、ユーザーに「スケジュールが超過している、新しい終了時刻を再計算している」などと表示できますが、異なるユーザーが同時に多くのスケジュール変更を入力すると、システムが劣化する可能性があります。その通知の1つの連続した表示に。ただし、少なくとも、次の再構築のために一定期間に発生する変更をバッチ処理できるという利点があります。

私が見たスケジューリングの問題のほとんどが実際にはリアルタイムの再計算を行わないのはこのためです。ERPの状況では、製造現場のスケジューリングを担当するスケジュールマスターがいて、変更はすべてそれらを介して行われます。「マスター」スケジュールは、各シフトの前に再生成され(シフトは12時間だったため、1日2回)、シフト中は、次の12時間のブロックまでマスタースケジュールをシャッフルしない「ローカル」変更によって遅延が処理されました。

はるかに単純な状況(ソフトウェア設計)では、その日の進捗レポートに応じて、スケジュールが1日1回更新されました。悪いニュースは、更新されたスケジュールとともに、翌朝のスクラム中に配信されました。

簡単に言えば、これはおそらく「質問をしない」瞬間であり、仮定に異議を唱える必要があると思います。再計算が十分に大きく、継続的な更新が実用的でない場合は、期待と現実を一致させることが適切です。アルゴリズムの作業(ローカルの変更に最適化)、ハードウェアファームの拡張、または「真実」の期待のタイミングを再調整する必要があります。

より洗練された答えは、「高価なプロセスを想定する」よりも詳細を率直に要求します。なぜなら、そのプロセスに対する適切な攻撃ポイントを知ることは不可能だからです。

于 2012-03-21T17:12:19.333 に答える