web-dev-qa-db-ja.com

cronジョブのフェイルオーバーを実行する方法は?

2つのDebianサーバーを使用して、一度に1つのサーバーでのみ呼び出すことができるcronジョブ用の強力なフェイルオーバー環境をセットアップする必要があります。

/etc/cron.d内のファイルを移動することでうまくいくはずですが、そのようなアクションを操作するための簡単なHAソリューションはありますか?そして可能であればハートビートではありません;)

8
Falken

ハートビート/ペースメーカーは、ジョブが一度に1つのホストでのみ実行されるようにするために、多くの競合状態やフェンシングなどを処理できるので、最良のソリューションだと思います。自分で何かを設計することは可能ですが、それらのパッケージが行うすべてのシナリオを説明できない可能性があり、最終的には、すべてではないにしても、ほとんどのホイールを交換することになります。

そのようなことを本当に気にせず、より簡単な設定が必要な場合。サーバー上のcronジョブを数分ずらすことをお勧めします。次に、ジョブがプライマリで開始されると、ジョブが動作する共有リソースに何らかの形でマーカーを残すことができます(これを指定しないため、意図的にあいまいにしています)。データベースの場合は、テーブルのフィールドを更新できます。共有ファイルシステムの場合は、ファイルをロックできます。

ジョブが2番目のサーバーで実行されると、マーカーの存在を確認し、存在する場合は中止できます。

5
Kamil Kisiel

簡単に言えば、cronスクリプトをある種のクラスター対応アプリケーションに変換する必要があります。必要に応じて軽量または重量の実装であるため、プライマリノードのフェイルオーバー後にアクションを適切に再開/再開(または状態を回復)できることが1つ必要です。些細なケースは、それらがステートレスプログラム(または「ステートレス十分な」プログラム)であり、いつでも簡単に再起動でき、問題なく動作することです。これはおそらくあなたのケースではありません。ステートレスプログラムの場合、すべてのノードで並列に実行するだけでよいため、フェイルオーバーは必要ありません。

通常は複雑なケースでは、スクリプトはクラスターの共有ストレージにあり、その状態をファイルに保存し、ディスクに保存されている状態をアトミックにのみ変更し、起動時に検出される一時的な状態からアクションを続行できる必要があります。

1
kubanczyk

要件に応じて2つのアプローチを使用します。どちらの場合も、cronが存在し、すべてのマシンから実行されますが、多少の健全性チェックが含まれます。

  1. マシンがプライマリとセカンダリ(複数のセカンダリが存在する可能性があります)の関係にある場合、スクリプトは、それらが実行されているマシンがプライマリ状態であるかどうかを確認するように変更されます。そうでない場合、彼らは単に静かに終了します。現時点ではHBの設定はありませんが、HBにこの情報を問い合わせることができると思います。

  2. すべてのマシンが適格なプライマリーである場合(クラスター内など)、いくつかのロックが使用されます。共有データベースまたはPIDファイルのいずれかを介して。ロックステータスを取得するマシンと、静かに終了しないマシンは1台だけです。

1
Dan Carley

実際、この分野で満足できる解決策はありません。私たちはそれらすべてを試しました。スクリプトソリューション、heartbeat/pacemakerを使用したcronなど。最近まで、唯一のソリューションはグリッドソリューションでした。当然のことながら、これは、グリッドソリューションがシナリオにとってやり過ぎであるため、私たちが見たいものではありません。

それが私がCronBalancerプロジェクトを始めた理由です。分散型で負荷分散されたHA(終了時)を除いて、通常のcronサーバーとまったく同じように機能します。現在、最初の2つのポイントは終了しており(ベータ版)、標準のcrontabファイルで機能します。

hAフレームワークが用意されています。残っているのは、フェイルオーバーとリカバリーのアクションを決定するために必要なシグナリングだけです。

http://sourceforge.net/projects/cronbalancer/

チャック

1

Nagios event handler を単純な解決策として使用してきました。

NRPEサーバーの場合:

command[check_crond]=/usr/lib64/nagios/plugins/check_procs -c 1: -C crond
command[autostart_crond]=Sudo /etc/init.d/crond start
command[stop_crond]=Sudo /etc/init.d/crond stop

nagiosユーザーをsudoersグループに追加することを忘れないでください。

nagios  ALL=(ALL)   NOPASSWD:/usr/lib64/nagios/plugins/, /etc/init.d/crond

無効化 requiretty

Defaults:nagios !requiretty

Nagiosサーバーの場合:

services.cfg

define service{
    use                     generic-service
    Host_name               cpc_3.145
    service_description     crond
    check_command           check_nrpe!check_crond
    event_handler           autostart_crond!cpc_2.93
    process_perf_data       0
    contact_groups          admin,admin-sms
}

commands.cfg

define command{
    command_name    autostart_crond
    command_line    $USER1$/eventhandlers/autostart_crond.sh $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$ $ARG1$
}

autostart_crond.sh

#!/bin/bash

case "$1" in
    OK)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c stop_crond
        ;;
    WARNING)
        ;;
    UNKNOWN)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c autostart_crond
        ;;
    CRITICAL)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c autostart_crond
        ;;
esac

exit 0

しかし、リソースが一度に1つのノードでのみ実行されるようにするための最良のソリューションであるため、 Pacemaker and Corosync を使用するように切り替えました。

これが私がしたことのステップです:

Crond initスクリプトがLSB準拠 であることを確認します。 CentOSで、要件に一致するように終了ステータスを1から0に変更する必要があります(実行を開始するか、停止を停止する場合)。

start() {
    echo -n $"Starting $prog: " 
    if [ -e /var/lock/subsys/crond ]; then
        if [ -e /var/run/crond.pid ] && [ -e /proc/`cat /var/run/crond.pid` ]; then
            echo -n $"cannot start crond: crond is already running.";
            failure $"cannot start crond: crond already running.";
            echo
            #return 1
            return 0
        fi
    fi

stop() {
    echo -n $"Stopping $prog: "
    if [ ! -e /var/lock/subsys/crond ]; then
        echo -n $"cannot stop crond: crond is not running."
        failure $"cannot stop crond: crond is not running."
        echo
        #return 1;
        return 0;
    fi

次に、以下を使用してペースメーカーに追加できます。

# crm configure primitive Crond lsb:crond \
        op monitor interval="60s"

crm configure show

node SVR022-293.localdomain
node SVR233NTC-3145.localdomain
primitive Crond lsb:crond \
        op monitor interval="60s"
property $id="cib-bootstrap-options" \
        dc-version="1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        stonith-enabled="false" \
        no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
        resource-stickiness="100"

crm status

============
Last updated: Fri Jun  7 13:44:03 2013
Stack: openais
Current DC: SVR233NTC-3145.localdomain - partition with quorum
Version: 1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ SVR022-293.localdomain SVR233NTC-3145.localdomain ]

 Crond  (lsb:crond):    Started SVR233NTC-3145.localdomain

3.145でPacemakerとCorosyncを停止してフェイルオーバーをテストします。

[root@3145 corosync]# service pacemaker stop
Signaling Pacemaker Cluster Manager to terminate:          [  OK  ]
Waiting for cluster services to unload:......              [  OK  ]

[root@3145 corosync]# service corosync stop
Signaling Corosync Cluster Engine (corosync) to terminate: [  OK  ]
Waiting for corosync services to unload:.                  [  OK  ]

次に、2.93でクラスターのステータスを確認します。

============
Last updated: Fri Jun  7 13:47:31 2013
Stack: openais
Current DC: SVR022-293.localdomain - partition WITHOUT quorum
Version: 1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ SVR022-293.localdomain ]
OFFLINE: [ SVR233NTC-3145.localdomain ]

Crond   (lsb:crond):    Started SVR022-293.localdomain
1
quanta

私はこの特定の問題のためにRcronを好みます。あなたは単に「アクティブ」または「パッシブ」と言う状態ファイルを持っていて、それがアクティブならあなたのcronは特定のマシンで実行されます。状態ファイルがパッシブに設定されている場合、実行されません。そのような単純な。

これで、RedHat Cluster Suiteまたはその他のクラスタリングミドルウェアを使用して、クラスター全体の状態ファイルを管理できます。または、特定のノードで手動でアクティブに設定することもできます。

0
Jakov Sosic

特定のマシンで実行する/実行しないようにするのは簡単です。提案したように、スクリプトでcronジョブを/etc/cron.dに配置するか、スクリプトを永続的に/etc/cron.dに配置しますが、スクリプト自体にフェイルオーバーチェックを実行させ、実行するかどうかを決定します。

これらの両方の共通(欠落)部分は、スクリプトが他のマシンのスクリプトが実行されているかどうかを確認する方法です。

あなたがやろうとしていることについてのより多くの情報がなければ、これは答えるのが難しいです。

0
Schof