15

PROCESS_IND= 'N' のレコードのテーブルをクエリし、何らかの処理を行ってPROCESS_INDから 'Y' に更新する単一のプロセスがあります。

このプロセスの複数のインスタンスを実行できるようにしたいのですが、同時実行の問題を回避するためのベスト プラクティスがわかりません。

どこから始めればよいですか?

4

5 に答える 5

12

私が使用するパターンは次のとおりです。

  • それぞれスレッド/プロセス/マシン ID とタイムスタンプである列「lockedby」と「locktime」を作成します (複数のマシン間で処理を分割する場合は、マシン ID が必要になります)。
  • 各タスクは、次のようなクエリを実行します。

    UPDATE taskstable SET lockedby=(my id), locktime=now() WHERE lockedby IS NULL ORDER BY ID LIMIT 10

10 は「バッチ サイズ」です。

  • 次に、各タスクは SELECT を実行して、処理のために「ロック」されている行を見つけ、それらを処理します。
  • 各行が完了したら、lockedby と locktime を NULL に戻します。
  • これはすべて、存在する数のバッチのループで行われます。
  • cron ジョブまたはスケジュールされたタスクは、おそらくハングまたはクラッシュしたタスクによって行われたため、ロック時間が長すぎる行の「lockedby」を定期的にリセットします。他の誰かがそれらを拾います

LIMIT 10 は MySQL 固有ですが、他のデータベースにも同等のものがあります。ORDER BY は、クエリが非決定論的であることを避けるためにインポートされます。

于 2009-02-20T08:46:00.433 に答える
5

意図は理解できますが、すぐに行レベルのロックに移行することに同意しません。これにより、応答時間が短縮され、実際に状況が悪化する可能性があります. テスト後に APL の同時実行性の問題が発生した場合は、最初に「データページ」ロックに繰り返し移行する必要があります。

この質問に適切に答えるには、関連するテーブル構造とインデックスに関するより多くの情報が必要ですが、さらに説明する必要があります。

DOL、データ行のロックは、全ページ/ページ レベルのロックよりも多くのロックを使用します。すべてのロックを管理するオーバーヘッドと、キャッシュ内のより多くのロック構造の要求による使用可能なメモリの減少により、パフォーマンスが低下し、より同時実行のアプローチに移行することで得られる可能性のある利益が相殺されます。

最初に APL で移動せずにアプローチをテストし (すべてのページ ロックの「デフォルト」)、問題が見られる場合は DOL に移動します (最初にデータページ、次にデータ行)。テーブルを DOL に切り替えると、そのテーブルのすべての応答がわずかに悪化し、テーブルがより多くのスペースを使用し、テーブルが断片化しやすくなり、定期的なメンテナンスが必要になることに注意してください。

つまり、すぐにデータ行に移動しないでください。最初に同時実行アプローチを試してください。問題がある場合は、最初にデータページのロックを使用し、最後にデータ行を使用してください。

于 2009-02-19T11:19:39.570 に答える
2

row level locking次を使用してテーブルで有効にする必要があります。

CREATE TABLE mytable (...) LOCK DATAROWS

次にあなた:

  • 取引を開始する
  • オプションで行を選択しFOR UPDATEます(ロックされます)
  • 好きなことをしてください。

トランザクションが終了するまで、他のプロセスはこの行に対して何もできません。

PSを使用することで発生する可能性のあるオーバーヘッドの問題に言及する人もいますLOCK DATAROWS

はい、オーバーヘッドがありますが、このようなテーブルではほとんど問題とは言えません。

しかし、次に切り替えると(デフォルトでは) DATAPAGES1 行につき 1 行しかロックできず、行が 1 ページに存在するプロセスは同時に実行できなくなります。PAGE2k

一度に数十行がロックされているテーブルについて話している場合、顕著なパフォーマンスの低下はほとんどありません。

そのような設計では、プロセスの並行性がはるかに重要です。

于 2009-02-18T20:58:11.530 に答える
1

最も明白な方法はロックです。データベースにロックがない場合は、「ロック済み」フィールドを追加して自分で実装できます。

同時実行を簡素化する方法のいくつかは、未処理のアイテムへのアクセスをランダム化することです。そのため、最初のアイテムで競合するのではなく、アクセスをランダムに分散します。

于 2009-02-19T05:33:32.290 に答える
0

プロシージャを単一のSQLステートメントに変換し、複数の行を単一のバッチとして処理します。これは、データベースが機能することになっている方法です。

于 2009-02-19T04:59:18.347 に答える