0

頻繁に繰り返される処理が必要なデータ/ジョブが多数 (数万) あります。処理されるジョブは、SQL Server 2012 (Web Ed) データベースに保存され、新しいジョブで頻繁に更新されたり、ジョブが削除される可能性があります。

サンプル:

Id     |  WorkItem
1      |  Copy X to Y
2      |  Ping stackoverflow.com
3      |  Verify backupset
4      |  Send an email

私の目標は、パフォーマンス上の理由と、ノードに障害が発生した場合でもジョブが確実に処理されるように、ジョブ処理を複数のノードに分散することです。

2 つの考慮事項:

  • すべてのジョブが最終的に何らかのノードによって実行されるようにする必要があります。また、ジョブがデータベース駆動型キューに追加されると、これが継続的に実行されるようにする必要があります。
  • すべてのノードに何らかの作業をさせ、単一のノードがほとんどの作業をフェッチしないようにしたいので、ある種のラウンドロビンを実装することは理にかなっているようです。

システム全体がノードの障害に耐えられる必要があるため、何が起きていて何が起きていないのかわからないため、作業をノードに実際に「割り当てる」ことはできません。これを回避するための最初の考えは、各ノードがデータベースから 1 つ以上のジョブを「フェッチ」し、それらを処理してから、データを SQL データベースに返すことでした。ただし、次のような問題があります。

  • ノードは、他のノードがすでに処理しているものを認識する必要があるため、ジョブが誤って 2 回処理されることはありません。これは、ジョブを処理中としてマークする必要があることを意味します。
  • これらのジョブの多くは非常に小さいですが、非常に頻繁に (おそらく 10 ~ 30 秒ごとに) 実行する必要があります。誰がジョブを処理しているかを絶えず更新し、ジョブを解放してから再度処理することは、データベースの大きなオーバーヘッドのように思えます。
  • ノードが処理中に停止した場合はどうなりますか? これから回復する方法はありますか?

この問題を解決する最も効率的な方法は何ですか? ありがとうございました!

4

2 に答える 2

1

SQL Serverの最適な構成を試す必要があるかもしれません(その専門家ではありません)...しかし、基本的なスキームは次のようになります。

  • ジョブ処理を管理するための5つの列があります
    。1つは処理ノードが停止した場合のフェイルセーフとして機能するDONEUNTILと呼ばれます...これは基本的に「推定処理完了時点」です...
    2つ目はNODE処理のIDを含むNODEIDと呼ばれますその仕事。
    3番目はDONEと呼ばれ、ジョブが終了するとセット1になります。
    4番目にCREATEDと呼ばれ、ジョブがテーブルに配置されたときのタイムスタンプが含まれています。
    5番目は主キーであるJOBIDと呼ばれます。

  • DONEUNTILとNODEIDをNULLに設定して、すべてのノードでDONEUNTILが通過し、DONE!=1であるすべてのジョブを頻繁にクリーンアップするようにします。

  • ノードが次のジョブを実行する準備ができたら、ノードはNODEIDとDONEにNULLを持つ最も古いCREATEDを持つJOBIDを選択します!= 1
    次に、処理を開始する前にDONEUNTILとNODEIDを適切に更新します。
    処理が終了すると、DONE=1が更新されます。

上記のバリエーションを使用できます。たとえば、ジョブの優先順位、再試行カウンターなどを使用したり、「ジョブ管理情報」を別のテーブルに配置したりできます。

このスキームは非常にうまく機能します...ジョブがたくさんある場合は、DONE = 1のジョブをアーカイブテーブルに移動するのが理にかなっているかもしれません...このように、ジョブテーブルにはアクティブなジョブ(処理待ちまたは処理中)のみが含まれます)スムーズに実行し続ける必要があります。

于 2012-12-16T21:45:50.453 に答える
0

確かにキューメカニズムを使用する必要があります-Sql Serverには、Sql Service Brokerと呼ばれる組み込みのキューメカニズムがあります。

于 2012-12-16T22:15:24.470 に答える