8

私はここで設計上の頭痛の種です。PHP と MySQL を Java と組み合わせて使用​​しています (私のプロジェクトは Android アプリケーションです)。サーバー側で一連の計算を定期的に実行する方法を決定する必要があります。SO には、cron ジョブの作成方法などに対処する豊富な資料があります。それは素晴らしいことです。これで終わりにすることもできますが、プロジェクトのこの部分に広い意味で取り組む方法についてはわかりません。

アプリケーションは、ユーザーの地理的な場所に完全に集中しています。それらは常に 4 から 40 の間のクラスターで編成されており、これらのクラスターは私のデータベースで 1 つのインスタンス レコードを形成します。これらのインスタンスは、いつでもアクティブまたは非アクティブになる可能性があります。

タスク

データベース内の各レコード、または各エポックでインスタンスの重心を再計算したい (これは簡単で、特に近接している場合はスカラー アプローチを使用します)、場所を効果的にシフトします。インスタンスのデータベース内の緯度と経度の値を更新することにより、インスタンス自体の。その後、ユーザーはホームに電話すると、これらの新しいインスタンスの重心座標を定期的に受け取ります。

メソッド

ここはランク未経験でややこしいところです。各エポックで、インスタンスごとに 1 つの SQL 選択クエリとそれに続く 1 つの SQL 更新操作を含む比較的単純な計算を作成することから始めました。今のところ約 20 ~ 30 秒の更新間隔を想定すると、それは 1 分未満です。明らかに、これは cron ジョブの 1 分の制限に違反しています。(絶対に必要な場合は、エポック間の時間差をハードコーディングできることに注意してください)。

短期的には、インスタンス/クラスターが非常に少ないため、このプロセスの実行にかかる時間はごくわずかです。ただし、インスタンスの数が数千に達した場合、後である時点ですべての計算を処理するために、多くの SQL クエリと多くの時間が蓄積される可能性があります...不要な負荷を減らすために、当然のことながら非アクティブなインスタンスを除外するメカニズムを組み込むことですが、必要な計算時間がエポック間隔を超える可能性があることはまだ考えられると思います。それは(かなり)後で問題になると思います。

質問

現在のところ、問題は 2 つあります。

  1. 各エポックですべてのアクティブなインスタンスに対して同じ単純な関数を実行したいと考えています。では、多くの反復を実行するよりも効率的な方法はありますか? 1 つの大きな最終的な SQL 更新クエリを使用して、一度に多数のテーブル行を更新することはできますか? mysqli_multi_query() のようなものは実際にここで非常に役立ちますか? (この時点で、私は mysqli を持っていません)。
  2. cron ジョブについて読んだ 1 分の制限に違反する可能性があるという事実を考慮して、各エポックでこのプロセスを再起動するタイマーまたはトリガーメカニズムを実装するにはどうすればよいですか?

私のアイデア

私の現在のアプローチは次のとおりです。

  1. 1 つの SQL 選択クエリを実行して、現在のエポックに合わせてすべてを設定し、重心シフトを必要とするインスタンス ID 番号をフェッチします。
  2. これらのインスタンス ID を PHP 配列に入力します。
  3. ループと 1 つまたは非常に多くの SQL 更新 (上記を参照) を使用して各インスタンスを順次シフトし、新しい座標ペアをデータベースに書き込みます。
  4. このタスクが各エポック (つまり、x 秒ごと) で実行されるようにスケジュールします。

上記のアプローチは健全ですか?現時点では、他に良い提案がない限り、この方法で行う予定です。各エポックでタスクを実行するようにスケジュールする方法については、実際にはしっかりとしたハンドルを持っていません (ポイント #4)。いくつかのガイダンスがなければ、私はまだあまり上手ではありません. :) いつものように、どんな提案でも大歓迎です。

4

1 に答える 1

4

スケジュールされたタスクから、必要に応じて更新するアプローチに移行することを検討してください。これはかなり簡単に実現できますが、トレードオフがあります。

  • Last Updated という日時フィールドを追加します。

  • オブジェクトにクエリを実行するたびに、最後に更新されたフィールドで
    「鮮度」を確認します (この場合、30 秒以上前の場合)。

  • 新鮮な場合は、データをユーザーに送信します。

  • 最新でない場合は、データを再計算してデータベースに保存します
    (最後に更新されたフィールドを必ず変更してください)。次に、新しい
    データをユーザーに送信します。

これにより、スケジュールされたタスクが不要になり、すべての行を更新する無駄がなくなります。ただし、ユーザーへの応答が遅くなる可能性があります。

于 2012-07-17T14:09:52.157 に答える