28

私はそれを理想的な解決策を見つけるのに苦労している問題を抱えています。それをよりよく説明するために、ここで私のシナリオを公開します。

複数のクライアントから注文を受け取るサーバーがあります。各クライアントは、指定された間隔で実行する必要がある一連の定期的なタスクを送信します。たとえば、クライアントAは、2009年12月31日から2010年12月31日まで1分ごとに実行する必要があるタスクAAを送信します。したがって、私の計算が正しければ、年間で約525 600の操作になります。クライアントとタスク が増えると、サーバーにこれらすべてのタスクを処理させることは不可能になるため、ワーカーマシンのアイデアを思いつきました。サーバーはPHPで開発されます。

ワーカーマシンは 、自宅や職場でホストする通常の安価なWindowsベースのコンピューターであり、各ワーカーには、停電を回避するための専用インターネット接続(動的IPを使用)とUPSがあります。また、各ワーカーはWebサービス呼び出しを介して約30秒ごとにサーバーにクエリを実行し、次の保留中のジョブをフェッチして処理します。ジョブが完了すると、ワーカーは出力をサーバーに送信し、新しいジョブなどを無限に要求します。システムを拡張する必要がある場合は、新しいワーカーを設定するだけで、すべてがシームレスに実行されます。ワーカークライアントはPHPまたはPythonで開発されます。

クライアントはいつでもサーバーにログオンして、注文したタスクのステータスを確認できるはずです。

ここで、注意が必要な部分が始まります。

  • 何らかの理由でサーバーがダウンした場合、すでに処理されたタスクを再構築できなければなりません。
  • ワーカーはクライアント固有ではありません。1人のワーカーが任意の数のクライアントのジョブを処理する必要があります。

一般的なデータベース設計と使用するテクノロジーについて疑問があります。

当初、私はいくつかのSQLiteデータベースを使用し、それらすべてをサーバー上で結合することを考えていましたが、クライアントごとにグループ化してジョブレポートを生成する方法がわかりません

memcachedCouchDBHadoopなどのテクノロジーを実際に使用したことはありませんが、これらのいずれかが私の問題に適しているかどうかを知りたいのですが、そうである場合は、初心者にどちらをお勧めしますか?私のような「分散コンピューティング」(またはこれは並列ですか?)。ワーカーには動的IPがあることに注意してください。

前に言ったように、一般的なデータベース設計にも問題があります。これは、特定のR(D)DBMSをまだ選択していないこともありますが、私が選択したDBMSに依存しない問題が1つあります。キューイングシステムへ...特定のジョブに対するすべての絶対タイムスタンプを事前に計算し、タイムスタンプのセットが大きい場合は、それらを実行して昇順で完了としてフラグを立てる必要があります。または、タイムスタンプモジュラス60 = =0->実行"。この「賢い」システムの問題は、一部のワーカーが過負荷状態になっている間、何もしないで待機している可能性があるため、一部のジョブが正常に実行されないことです。何を指示してるんですか?

PS:この質問のタイトルとタグが私の問題と私がやろうとしていることを適切に反映しているかどうかはわかりません。そうでない場合は、それに応じて編集してください。

ご入力いただきありがとうございます。

@timdev:

  1. 入力は非常に小さいJSONエンコード文字列になり、出力もJSONエンコード文字列になりますが、少し大きくなります(1〜5 KBのオーダー)。
  2. 出力はWebから利用可能ないくつかのリソースを使用して計算されるため、主なボトルネックはおそらく帯域幅です。R(D)DBMSによっては、データベースへの書き込みも1つになる場合があります。
4

7 に答える 7

15

ギアマンを再現しようとしているようです。Gearmanの紹介は次のとおりです。

Gearmanは、作業を行うのにより適した他のマシンまたはプロセスに作業をファームアウトするための汎用アプリケーションフレームワークを提供します。これにより、並列作業、負荷分散処理、および言語間の関数の呼び出しが可能になります。高可用性Webサイトからデータベース複製イベントの転送まで、さまざまなアプリケーションで使用できます。言い換えれば、それは分散処理がどのように通信するかについての神経系です。

クライアントとバックエンドワーカーの両方のコードをPHPで記述できます。


Windows用にコンパイルされたGearmanサーバーについての質問を再確認してください。Windows用に事前に構築されたきちんとしたパッケージで利用できるとは思いません。Gearmanはまだかなり若いプロジェクトであり、Windows用のすぐに実行できるディストリビューションを作成するまでには成熟していない可能性があります。

Sun /MySQLの従業員であるEricDayとBrianAkerは、2009年7月にOSCONでGearmanのチュートリアルを行いましたが、スライドにはLinuxパッケージのみが記載されています。

Perl CPANテスタープロジェクトへのリンクは次のとおりです。これは、Gearman-ServerがMicrosoft Cコンパイラ(cl.exe)を使用してWin32上に構築でき、テストに合格することを示しています: http://www.nntp.perl.org/group/perl。 cpan.testers / 2009/10 / msg5521569.html しかし、ソースコードをダウンロードして自分でビルドする必要があると思います。

于 2009-10-05T00:20:35.740 に答える
4

Gearmanは、このシナリオの最適な候補のようです。必要なコンピューティング能力に応じて、Windowsマシンをマシンごとに複数のワーカーノードに仮想化することもできます。

また、gearmanの永続キューシステムは、ワーカーまたはgearmanサーバーがクラッシュしたときにジョブが失われるのを防ぎます。サービスを再起動した後、キューはクラッシュ/再起動前に中断したところから続行されます。アプリケーションでこれらすべてを処理する必要はありません。これは大きな利点であり、時間/コードを大幅に節約できます。

カスタムソリューションを作成することはうまくいくかもしれませんが、ギアマンの利点、特に永続的なキューは、これが現時点であなたにとって非常に良いソリューションである可能性があるように私には思えます。ギアマン用のWindowsバイナリについてはわかりませんが、可能であると思います。

于 2009-10-13T23:58:48.270 に答える
3

より簡単な解決策は、複数のphpノードが接続された単一のデータベースを持つことです。適切なRDBMSを使用する場合(MSql + InnoDBでもかまいません)、1つのテーブルをキューとして機能させることができます。次に、各ワーカーはそこからタスクをプルして作業し、完了時にトランザクションを使用してデータベースに書き戻し、同期するためにロックします。これは、入出力データのサイズに少し依存します。それが大きい場合、これは最良のスキームではないかもしれません。

于 2009-10-05T07:00:22.723 に答える
3

この種のタスクではsqliteを避けますが、小さなアプリにとっては非常に素晴らしいデータベースですが、同時実行性をうまく処理できません。データベース全体をロックし、単一のトランザクションまでロックしたままにするロック戦略が1つだけあります。完了です。

産業用の強力な同時実行性とロック管理を備え、複数の同時トランザクションを非常にうまく処理できるPostgresを検討してください。

また、これはキューイングの仕事のように聞こえます!Javaの世界にいる場合は、ソリューションにJMSベースのアーキテクチャをお勧めします。phpで同様のことを行う「dropr」プロジェクトがありますが、すべてかなり新しいため、プロジェクトに適していない可能性があります。

どちらの技術を使用する場合でも、中央プロセスが選択したワーカーにタスクを割り当てる「コマンドエコノミー」ではなく、ワーカースレッドが利用可能な「ジョブ」をできるだけ早く消費する「フリーマーケット」ソリューションを選択する必要があります。

于 2009-10-15T01:56:51.760 に答える
3

マスターサーバーと複数のワーカーのセットアップは、あなたのケースでは正しいように見えます。

マスターサーバーでは、マスターマスターレプリケーションにMySQL(Percona InnoDBバージョンは安定していて高速です)をインストールするので、単一障害点は発生しません。マスターサーバーは、ワーカーがN秒ごとにプルするAPIをホストします。マスターは、使用可能なジョブがあるかどうかを確認します。ある場合は、ジョブがワーカーXに割り当てられていることを示すフラグを立て、適切な入力をワーカーに返します(これはすべてHTTP経由で行われます)。また、ここでは、ワーカーのすべてのスクリプトファイルを保存できます。

ワーカーについては、Linuxディストリビューションをインストールすることを強くお勧めします。Linuxでは、スケジュールされたタスクを設定する方が簡単で、一般的にはその仕事に適していると思います。Linuxを使用すると、完全に構成されたワーカーを使用してライブCDまたはISOイメージを作成し、必要なすべてのマシンにすばやく簡単にインストールすることもできます。次に、マスターサーバーとRSyncしてスクリプトを更新/変更するcronジョブを設定します。このようにして、ファイルを1か所(マスターサーバー)で変更すると、すべてのワーカーが更新を取得します。

この構成では、ワーカーがマスターに接続しているため、IPやワーカーの数は気になりません。その逆も同様です。

ワーカージョブは非常に簡単です。APIにジョブを要求し、それを実行し、APIを介して結果を送り返します。すすぎ、繰り返します:-)

于 2009-10-17T04:20:54.730 に答える
3

SQLを介してキューイングホイールを再発明するのではなく、システムのコアとしてRabbitMQActiveMQなどのメッセージングシステムを使用できます。これらの各システムはAMQPプロトコルを提供し、ハードディスクでバックアップされたキューを備えています。サーバーには、スケジュールに従って新しいジョブを「ワーカー」キューにプッシュするアプリケーションと、「結果」キューからの結果をデータベースに書き込む(または他の方法で動作する)アプリケーションがあります。

すべてのワーカーはRabbitMQまたはActiveMQに接続します。彼らは作業を作業キューから取り出し、作業を行い、応答を別のキューに入れます。それを行った後、彼らは「完了した」と言うために元のジョブ要求をACKします。ワーカーが接続を切断すると、ジョブはキューに復元され、別のワーカーがそれを実行できるようになります。

キュー以外のすべて(ジョブの説明、クライアントの詳細、完了した作業)をデータベースに保存できます。しかし、リアルタイムのものはどこかに置く必要があります。私自身の仕事では、ライブの電力使用量データをストリーミングしているので、多くの人がデータベースにアクセスしてポーリングするのは悪い考えです。システム内のライブデータについて書きました。

于 2009-10-19T03:06:18.493 に答える
1

私はあなたがマスタージョブディストリビューターと労働者と正しい方向に進んでいると思います。HTTP経由で通信してもらいます。

スクリプト(Cではexecvp、JavaではSystem.Desktop.something)を実行する機能があるため、クライアントとしてC、C ++、またはJavaを選択します。ジョブは、スクリプトの名前とそのスクリプトの引数である可能性があります。クライアントにジョブのステータスを返してもらうことができます。ジョブが失敗した場合は、再試行できます。クライアントに毎分(またはx秒ごとに)ジョブをポーリングさせ、サーバーにジョブを分類させることができます。

PHPはサーバーで機能します。

MySQLはデータベースに対して正常に機能します。開始と終了の2つのタイムスタンプを作成します。サーバー上で、WHEN SECONDS==0を探します

于 2009-10-04T18:43:11.457 に答える