2009-07-04 7 views
0

私はキューシステムの実装の難しさを見つけようとしています。私は基本的なキューを実装する方法を知っているので、バックグラウンドで私が何をしているのか少し説明します:キューアクセス同時実行ソリューションとは何ですか?

私は、メッセージが配置されるキューを実装します。メッセージは、ユーザーが定義した時間に掲示されるように予定されています(複数の出現は分の精度で許可されますが、UIの観点からは「毎分または毎時間」の出現が制限されますが、この)。

ここに私の質問が出てくるところです: 最終的に私は現時点で多くのメッセージを掲示する必要がある状況にあるかもしれません。スクリプト)を実行して、[x、10,25]個のメッセージを一度にキューから取り出して処理します。問題は、各インスタンスが一意のメッセージを処理するように(これはすでに別のインスタンスによって処理されているものを処理することなく)行う方法です。私は現在の接続、レコードをロックする方法、そして私が考えていないかもしれない何かを心配しています。

私が使用するテクノロジは、PHPとMySQLです。私は上記のいくつかの解決策を探しています、私は自分の検索で使用すべき用語、現実世界の例、考え、コメント、アイデアを探していますか?

ありがとうございました!私が出会った

一つの解決策は、アマゾンシンプルなキューサービスを使用していた...それはユニークなメッセージ処理/まあ、私はこのようにそれを行うだろうhttp://aws.amazon.com/sqs/

答えて

5

をロック約束:

メッセージのためのあなたのテーブルを作成し、もう2つのフィールド、 "PROCESS_ID"と "PROCESS_TIME"を追加してください。これらについては後で説明します。

各プロセスに一意のIDを付けます。起動時(GUIDなど)に生成することも、GUIDを自分で割り当てることもできます(より簡単に区別できます)。

  1. UPDATE messages SET process_id=$id, process_time=now() where process_id is null LIMIT 20
  2. SELECT * process_idを= $ idは

このございますメッセージFROM:プロセスがメッセージの束を取得したい

は、それは、このような何かを行います20個の「空き」メッセージを「ロック」します。次に、ロックして処理したメッセージが検索されます。各メッセージが処理された後、DELETEです。

UPDATEステートメントは、特に、トランザクション内のそのようなステートメントを自動的にラップするInnoDBを使用する場合は、非常にアトミックでなければなりません。 MySQLはそこでのすべての並行処理を処理する必要があります。

PROCESS_TIMEフィールドはオプションですが、これを使用してプロセスがハングアップしたときを確認できます。メッセージが長時間ロックされていると、何かが間違って調査されたと判断できます。オンラインソリューションの

+0

私は正しいことを理解しています:MySQLは各アップデートを受け取った順に処理する必要があります。また、同時に2つのアップデートが受信された場合、MySQLは内部的にそれを処理する必要があります。このリンク? – farinspace

+0

MySQLのドキュメントでInnoDBについてのセクションを見てください。取引に関する部分に注意を払う。 しかし、私はこれがトランザクションサポートを持たないMyISAMの下でも機能するかもしれないと思います。 2つのUPDATE文を同時に実行できる場合でも、同じ行に同時にアクセスできないようにする必要があります。もしそうなら、これは大きな混乱を招くでしょう。しかし、それができなければ、あなたはすでに安全です。 UDPATEがどの行に影響を与えるのかを正確に予測することはできませんが、2つのUPDATEが競合することはないことがわかります。 –

+0

このデータベースパターンでは、たくさんのキューのメッセージをポーリングすると思いますか? – Alfred

0

カップル:

  1. Amazon SQS
  2. Google appengine queue system

私はGoogleのソリューションは、(あまり使っていない場合でも、無料のだろう)はるかに安いですね。

私もPHP/MySQLと使用の思いで待ち行列を実装することを考えてきた:ロックのいくつかの並べ替えを実装する

  1. mysqlのget_lock
  2. メモリキューがディスクキュー上ではるかに高速であるため、memory heapデータストアにキューを入れてください。しかし、コンピュータがクラッシュしたときにデータを失うリスクがあります。
  3. named pipesを使用してプロセスと通信します。
1

この問題を回避することができます。

キューから物事を同時に取り出す問題の代わりに。あなたがそれを取得するとすぐにすべての情報を公開する。 しかし、は、特定の時間まで表示されないようにするというルールで公開しています。このようにすると、ロック/競合の問題を回避できます。

+0

私はそれが好きです...興味深い考え、私は解決策としてこのことを念頭に置いています...私の状況は少し異なりますが、実際にサードパーティシステムにメッセージを公開するAPIと対話します。 – farinspace

1

Beanstalkdメッセージキューを参照してください。 PHPクライアントがあります。 Beanstalkdの素晴らしい機能の1つ(例えばdroprとは対照的に)は、メッセージを遅らせることができます。つまり、キューにメッセージを投稿することができ、X秒が経過するまでクライアントに配信されません。

しかし、Beanstalkdには大きな欠点が1つあります。これはインメモリキューです。つまり、そのマシン(またはマシン)がクラッシュした場合、キューは空になり、内容は失われます。持続性は、次のバージョンのBeanstalkdで計画されている機能です。

+0

これまでしばらくしていたもの: -b

binlogを使用して、永続ストレージ上のジョブをに保ちます。起動時に、beanstalkdは、にあるバイナリログを回復し、通常の操作中に新しいジョブと状態の変更をbinlogに追加します。 – Kurt

+0

クール、ありがとう。私はすべての私のbeanstalkdのインスタンスをアップグレードしています。 –

関連する問題