web-dev-qa-db-ja.com

クラスタ内の1つのアプリケーションのみがジョブを実行します

次のシナリオでのベストプラクティスについて質問があります。

要件

2つのステップがある毎日のプロセスがあります:

  1. 数十のデータベースシャードにわたる構成データのクエリ
  2. アプリケーションのクラスター全体で、その構成データに基づいて多くの集中的なジョブを実行します

最初のステップは軽量で、単一のアプリケーションでのみ実行できます。そうしないと、重複するクエリが実行されます。その後、ジョブをアプリケーションクラスター全体に分散できます

質問

クラスタ内の1つのアプリケーションのみが最初のステップを実行するように強制するにはどうすればよいですか?

アイデア

  1. データベースのロック
    • 各アプリケーションは同時に(たとえば、cronを介して)起動し、ロックを取得しようとします。 1つだけが成功します。この勝者はステップ1を実行した後、クラスター内のすべてのアプリケーションに作業を分散します。
  2. 毎日単一のキューメッセージをクラスターに送信します。どのアプリケーションが最初にポーリングした場合でも、ステップ1でクエリを実行してから、クラスター全体(それ自体を含む)に作業を分散します。
  3. 別のシングルトンアプリケーション(クラスターの外部)を作成して、手順1を実行してから、作業を分散します。
1

あなたの2つのステップはほとんど無関係のように私には思えます。それらの間にはデータフローの依存関係がありますが、すでに別々に実行することを計画しています。したがって、メッセージキューを介して通信する完全に別個のプロセスにします。

これは基本的に、ソリューション2と3の中間です。クラスターで構成収集ジョブをスケジュールすることはできます。長期的には、すべてのプロセスを均一にデプロイする方が簡単になる可能性があります。この構成ジョブはほとんどの時間アイドル状態になるため、専用のクラスターノードは必要なく、ごくわずかなリソースしか消費しません。

メッセージキューの構成方法によっては、ソリューション2を直接実装することはお勧めできません。 1:nまたはn:1キューは、「すべてのプロセスがメッセージを書き込むことができ、すべてのプロセスがメッセージを受信する必要がある」アーキテクチャに必要なn:mキューよりもはるかに単純なデータフローを提供します。

1
amon