Linuxでの高可用性ミドルウェア、第3回: IBM LoadLeveler

高可用性とサーバー負荷平衡を一致させる

オンデマンド・ビジネスにおいて、マシンの負荷管理は非常に重要です。IBM ® LoadLeveler ® はジョブ管理システムであり、これを使うことによってジョブのプロセス要求と使用可能リソースを一致させ、より少ない時間で、より多くのジョブを実行できるようになります。今日では、ジョブ管理システムの稼働時間を最大限に維持することが次第に重要になってきています。ここではLoadLevelerに組み込みの高可用性機能を使ってLoadLevelerクラスターの高可用性を実現する方法、そしてオープン・ソースの高可用性ソフトウェアを使って、それをさらに強化する方法について学びます。

Hidayatullah Shaikh (hshaikh@us.ibm.com), Senior Software Engineer, IBM

Hidayatullah H. ShaikhはIBM T.J. Watson Research Centerのオンデマンド・アーキテクチャーと開発チームのシニア・ソフトウェア技術者です。関心領域は広く、ビジネス・プロセスのモデル化と統合、サービス指向アーキテクチャー、グリッド・コンピューティング、eコマース、エンタープライズJava、データベース管理システム、それに高可用性クラスターに渡っています。連絡先はhshaikh@us.ibm.comです。



2005年 2月 28日

IBM LoadLevelerはワークロード管理システムであり、これを使うことによってリソース・プールに対してジョブを実行依頼したり、スケジューリングしたり、実行したりできるようになります。またクラスター・リソースを最適利用するための、動的スケジューリングやワークロード・バランシングも提供しています。さらに、効果的なジョブ管理や負荷管理を行うための集中制御点にもなるものです。

LoadLevelerは各クライアント・マシン上で、デーモンのセットとして実行します。中央マネージャー・マシンにレポートするクライアント・マシンの一群はLoadLevelerクラスターと呼ばれ、またLoadLevelerクラスターはコンフィギュレーション・ファイルで定義されます。

この記事を最大限に利用するには、IBM LoadLevelerと高可用性クラスターを基本的に理解している必要があります。また、このシリーズの第1回の記事、 Linuxでの高可用性ミドルウェア、第1回: HeartbeatとApache Webサーバー もよく読んでおく必要があります。

高可用性用にLoadLevelerを実装する

LoadLevelerクラスターの各マシンは、ジョブのスケジューリングに関して、一つ以上の役割を果たします。こうした役割と、それがフェールした場合に何が起きるかを次に示します。

  • スケジューリング・マシン: ジョブを実行依頼すると、その実行依頼はスケジューリング・マシンが管理するキューに置かれます。スケジューリング・マシンは中央マネージャー(この役割は次に説明します)に対して、ジョブを実行できるマシンを見つけるように依頼し、またスケジューリング・マシンは、ジョブに関する情報を持続的にディスク上に保持します。

    ある1台のスケジューリング・マシン上のジョブ情報は通常、LoadLevelerクラスターにある他のスケジューリング・マシンからアクセスされたり共有されたりすることはありません。スケジューリング・マシンは独立に動作し、スケジューリング・マシンがフェールすると、フェールしたスケジューリング・マシン上にあったジョブ情報は一時的に使用不可となります(失われるわけではありません)。スケジュールを待っているジョブが、この期間に実行を考慮されることはありません。できるだけ早く、スケジューリング・マシンを再立ち上げすることが非常に重要です。スケジューリング・マシンに対する高可用性構成の例では、必要なローカル・ファイルやディレクトリーは外部の共有ディスク・ストレージに置かれるため、スケジューラー・ノードがフェールした場合には、バックアップのスケジューリング・マシンで使えるようになっています。

  • 中央マネージャー・マシン: 中央マネージャー・マシンの役割は、ジョブの要求内容に基づいて、そのジョブを実行するマシンを1台以上、LoadLevelerクラスターの中で見つけることです。そうしたマシンを見つけると、中央マネージャー・マシンはスケジューリング・マシンに通知します。

    中央マネージャー・マシンはLoadLevelerにとっての中央制御点です。LoadLevelerを使うと、代替の中央マネージャーを定義でき、プライマリー中央マネージャーがフェールした場合には、これがプライマリー中央マネージャーの役割を引き継ぎます。これについては、後の方のセクションで詳しく説明します。

    代替中央マネージャーが定義されていない場合に中央マネージャーがフェールすると、既に開始されていたジョブは最後まで実行されますが、ジョブの状態はユーザーにレポートされない可能性があります。新しいジョブはスケジューリング・ノードが受け付け、後で中央マネージャーが復帰した時、あるいは代替マネージャーが引き継いだ時に、中央マネージャーに転送されます。

  • 実行マシン: ジョブを実行するマシンは実行マシンとして知られています。

    実行ノードがフェールすると、そのノード上で実行していたジョブはフェールするため、ノードが復帰した時に再起動する必要があります。ジョブは最初から、あるいは最後のチェックポイントから実行します。ジョブのチェックポイントはオプションとして、あるいはアプリケーションの中にコード化します。バックアップの実行ノードを確立しておくと、より迅速にジョブを再起動できるようになります。バックアップ・ノードの有無に関わらず、適切なケーブル接続とディスク手法を使ってディスクにアクセスできる限り、ジョブとそのジョブ情報やチェックポイントは、ノードがフェールしても失われることはありません。

    スケジューリング・ノードと実行ノードの両方が、ジョブの状態に関する情報を持続的に保持します。スケジューリング・ノードと実行ノードは、(あるプロトコルを使って)少なくともどれか1つのノードが、ディスクに必ず状態情報を保存するようにします。これによって、フェールが起きた場合でも、状態はスケジューリング・ノードまたは実行ノードから確実に回復できることになります。スケジューリング・ノードも実行ノードも、他方のノードにジョブ情報が渡され、受け付けられるまで、そのジョブ情報を破棄することはありません。この記事で説明する構成では、ジョブ情報は共有ディスク上に保存されます。

  • 実行依頼マシン: このマシンは、ジョブを実行依頼し、クエリーし、中止します。そして、ジョブに関する情報は何ら持ちません。その情報が無いことから、こうしたマシンでは高可用性はそれほど重要ではありません。

クライアント・マシンが果たす役割は、そのマシン上で、どのLoadLevelerデーモンが構成されているかに依存します。全体として見るとLoadLevelerクラスターは、直列または並列のバッチ・ジョブを構築し、実行依頼し、実行し、管理します。

以下のセクションでは、高可用性に関してLoadLevelerが持っている組み込み機能の幾つかについて、また全体的なシステム可用性がハートビートを使うことでいかに高められるかについて、解説して行きます。


IBM LoadLevelerをインストールする

このセクションでは、IBM LoadLeveler 3.2 for Linux ™ha1ha2ha3 という3台のマシンにインストールする方法を説明します。これらのステップは、LoadLeveler Installation Memoドキュメント( 参考文献 にリンクがあります)のChapter 4に示されている概略に基づくものです。

  1. LoadLevelerに対するディレクトリーを次のように作成する
    • ローカル・ディレクトリー: /var/loadl
    • ホーム・ディレクトリー: /home/loadl
    • リリース・ディレクトリー: /opt/ibmll/LoadL/full
    • 中央マネージャー・マシンの名前: ha
  2. rootとしてログインする
  3. loadlグループ名を作る 下記のコマンドで、全ノード上に、グループIDとして1000を持つloadlグループが作られます。
    groupadd g 1000 loadl
  4. loadlユーザーIDを作る 下記のコマンドで、全ノード上に、ユーザーID、 loadlが作られます。
    useradd c loadleveler_user -d /home/loadl -s /bin/bash \
            -u 1000 g 1000 -m loadl
  5. LoadLeveler RPMをインストールする
    1. ライセンスRPM(LLIMAGEDIRがインストールRPMSを含んでいます)をインストールする
      cd $LLIMAGEDIR
      	rpm -Uvh LoadL-full-license-3.2.0.0-0.i386.rpm
    2. 他のRPMをインストールする。
      cd /opt/ibmll/LoadL/sbin
      	./install_ll -y -d "$LLIMAGEDIR"
  6. 初期化スクリプトllinitを実行する
    1. ローカル・ディレクトリーを作る。
      mkdir /var/loadl
    2. 所有権を設定する。
      chown loadl.loadl /var/loadl
    3. loadl IDに切り換える。
      su - loadl
    4. 下記を入力して、カレント・ディレクトリーをリリース・ディレクトリーのbinサブディレクトリーに変更する。
      cd /opt/ibmll/LoadL/full/bin
    5. LoadLevelerのhome、local、/tmpの各ディレクトリーで、書き込み権限があることを確認する。
    6. 下記に示すように llinit コマンドを入力する。
      ./llinit -local /var/loadl -release /opt/ibmll/LoadL/full -cm ha

高可用性のスケジューリング・マシン構成を作る

この設定では、以下のようになります。

  • マシン ha1 はプライマリー・スケジューリング・マシンとして動作する。
  • マシン ha2 は、スタンバイ・スケジューリング・マシンとして動作する。
  • マシン ha3 は、ジョブ実行マシンとして動作する。

高可用性の構成では、 ha1 に必要なローカル・ファイルやディレクトリーは外部の共有ディスク・ストレージに置かれるため、スケジューラー・ノードがフェールした場合には、 ha2 で使えるようになります。この設定方法は次の通りです。

  1. ノード ha1ha2 でrootとしてログインする。
  2. 共有ディスク(/ha)に次のディレクトリーを作る。
    • /ha/loadl/execute
    • /ha/loadl/spool
  3. ノード ha1 で次のコマンドを実行し、所有権を設定する。
    chown loadl.loadl /ha/loadl/
    chown loadl.loadl /ha/loadl/execute
    chown loadl.loadl /ha/loadl/spool
  4. ノード ha1ha2loadlIDに切り換える。
    su - loadl
  5. ノード ha1 で次のコマンドを実行し、共有ディレクトリーに適当なパーミッションを設定する。
    chmod 0777 /ha/loadl/execute
    chmod 775 /ha/loadl/spool
  6. ノード ha1ha2 で、/var/loadlの下にあるexecuteディレクトリーとspoolディレクトリーを削除する
    rm -rf /var/loadl/execute
    rm rf /var/loadl/spool
  7. ノード ha1ha2 で次のコマンドを使い、共有ディレクトリーへのシンボリック・リンクを作る。
    ln -s /ha/loadl/execute /var/loadl/execute
    ln -s /ha/loadl/spool /var/loadl/spool
  8. マシンの定義ファイルを編集する。下記は、それぞれのノード上での(/home/loadlの下にある)LoadL_adminファイルのうち、関係のある部分を示したものです。
    1. ha1 はプライマリー・スケジューリング・マシンとして、また中央マネージャーとして動作します。実稼働環境では、中央マネージャーとスケジューリング・デーモンは別々のマシンに置くことを推奨します。
      ...
      	ha1:   type = machine
      	       central_manager = true
      	       schedd_host = true
      	ha3:   type = machine
      	...
    2. ha2は、バックアップのスケジューリング・マシン/中央マネージャーとして動作します。
      ...
      	ha2:   type = machine
      	       central_manager = true
      	       schedd_host = true
      	ha3:   type = machine
      	...
    3. ha3 は、実行マシンとして動作します。
      ...
      	ha:    type = machine
      	       central_manager = true
      	       schedd_host = true
      	ha3:   type = machine
      	...
  9. それぞれのマシンで、(/home/loadlの下にある)LoadL_configファイルにある RUNS_HERE フラグを次のように変更します。
    1. ha1とha2
      ...
      	SCHEDD_RUNS_HERE        =       True
      	STARTD_RUNS_HERE        =       False
      	...

      これによって、スケジューリング・マシンではジョブが実行されなくなります。つまり ha1ha2 を、スケジューリング・マシンとしてのみ動作するようにするのです。

    2. ha3
      ...
      	SCHEDD_RUNS_HERE        =       False
      	STARTD_RUNS_HERE        =       True
      	...
  10. 3つのノード上の/etc/hostsファイルを次のように編集します。

    1. ha1
      ...
      	9.22.7.46    ha.haw2.ibm.com ha
      	9.22.7.46    ha2.haw2.ibm.com ha2
      	...
    2. ha2
      ...
      	9.22.7.46    ha.haw2.ibm.com ha
      	9.22.7.46    ha1.haw2.ibm.com ha1
      	...
    3. ha3
      ...
      	9.22.7.46    ha.haw2.ibm.com ha
      	9.22.7.46    ha1.haw2.ibm.com ha1
      	9.22.7.46    ha2.haw2.ibm.com ha2
      	...

スケジューリング・マシンを管理するようにハートビートを設定する

LoadLevelerを管理するように、ハートビートを下記のように設定します。

  1. LoadLevelerプロセスを起動停止するためのスクリプトを作ります。リスト1は、非常に基本的なスクリプトです。これは皆さんの設定に合わせてカスタマイズすることができます。このスクリプトを/etc/rc.d/init.dディレクトリーに置きます。
    リスト1. loadlスクリプト
    #!/bin/bash
    #
    #	/etc/rc.d/init.d/loadl
    #
    # Starts the loadleveler processes
    #
    # chkconfig: 345 89 56
    # description: Runs loadleveler
    . /etc/init.d/functions
    # Source function library.
    PATH=/usr/bin:/bin:/opt/ibmll/LoadL/full/bin
    #======================================================================
    SU="sh"
    if [ "`whoami`" = "root" ]; then
        SU="su - loadl"
    fi
    #======================================================================
    start() {
    	echo "$0: starting loadleveler"
    	$SU -c "llctl start"
    }
    #======================================================================
    stop() {
    	echo "$0: Stoping loadleveler"
    	$SU -c "llctl stop"
    }
    
    case $1 in
    'start')
        start
        ;;
    'stop')
        stop
        ;;
    'restart')
        stop
        start
        ;;
    *)
        echo "usage: $0 {start|stop|restart}"
        ;;
    esac
  2. 今度は(両方のスケジューリング・マシンにある)/etc/ha.d/haresourcesファイルを設定して、上記のloadlスクリプトを含むようにします。修正されたファイルのうち、関連する部分を次に示します。

    ha1.haw2.ibm.com 9.22.7.46 Filesystem::hanfs.haw2.ibm.com:/ha::/ha::nfs::rw,hard loadl

    この行は、ハートビートの起動時に、ha1にクラスターIPアドレスを提供し、共有ファイルシステムをマウントさせ、それからLoadLevelerデーモンを起動させます。シャットダウン時には、ハートビートは最初にLoadLevelerを停止し、それから共有ファイルシステムをアンマウントし、最後にIPを解放します。


スケジューリング・マシンのフェールオーバーのテスト

このセクションでは、スケジューリング・デーモンの高可用性のテスト方法を説明します。

  1. ハートビートを開始する: プライマリー・ノードで、次にバックアップ・ノードで、次のコマンドを使ってハートビート・サービスを開始します。

    /etc/rc.d/init.d/heartbeat start

    ハートビートが問題なく起動すると、ha.cfファイルで設定したIPアドレスを持った、新しいインターフェースが見えるはずです。一旦ハートビートが起動したら、プライマリーでログ・ファイル(デフォルトは /var/log/ha-log)を覗き、IPの引き継ぎを行ってからLoadLevelerを起動していることを確認します。 ps コマンドを使って、LoadLevelerデーモンがプライマリー・ノードで実行していることを確認します。バックアップ・ノードでは、ハートビートが上記のプロセスを起動することはありません。それが起きるのは、プライマリーがフェールした後のみです。

  2. Loadlevelerデーモンを開始する: 次のコマンドを使い、ユーザー loadl として、ha3 でloadlevelerデーモンを開始します。

    llctl start
  3. ha3を使用不可にする:startd デーモンを排出状態にすることにより、実行マシンとしてha3を使用不可にします。これは、ジョブを実行依頼した後、フェールオーバーのテストに充分な時間を与えるために必要です。ノードha3 でユーザー loadl として、下記のコマンドを使います。

    llctl drain startd
  4. LoadLevelerクラスターでどんなジョブがスケジュールされているかを、 ha1 マシンでユーザー loadl として下記のコマンドを使って調べます。

    llq

    この設定でのコマンド出力を図1に示します。このコマンドは、LoadLevelerクラスター上にあった、古い、完全に終了していないジョブを全てリストアップします。

    図1. ノードha1でのコマンドllqの出力
    Output of the command llq on node ha1

    ha1マシンでユーザーloadlとして下記のコマンドを実行し、LoadLevelerクラスター上のマシンの状態を調べます。

    llstatus
    図2. ノードha1でのコマンドllstatusの出力
    Output of the command llstatus on node ha1

    図2を見ると、ha1マシンにScehddがあることが分かります。また上記のステップ3により、ha3マシンでStartdが排出状態にされていることが分かります。

  5. samplesディレクトリーの所有権を設定する:ノードha3 (ここでジョブが実行されます)で下記のコマンドを使ってサンプル・ディレクトリーの所有権を設定します。

    chown loadl.loadl /opt/ibmll/LoadL/full/samples
  6. ジョブを実行依頼する: マシン ha1 でユーザー loadl として下記のコマンドを実行し、LoadLevelerに付属しているサンプル・ジョブの一つを実行依頼します。

    cd /home/loadl/samples
    llsubmit job1.cmd

    無事成功すると、下記のようなメッセージが出るはずです。

    llsubmit: The job "ha1.haw2.ibm.com.23" with 2 job steps has been submitted.

    サンプル、job1は2ステップのジョブであり、新しいジョブ・ステップが2つ作られるはずです。これら2つの新しいジョブ・ステップは、実行マシンが使用できないため、アイドル状態( I )に入ります。図3を見てください。

    図3. job1を実行依頼した後の、ノードha1でのコマンドllqの出力
    Output of the command llq on node ha1 after job1 is submitted

    では、プライマリー・スケジューリング・マシンをフェールさせましょう。

  7. フェールオーバーをシミュレートする: これは単に下記のコマンドを使って、プライマリー・システムでハートビートを停止するだけです。

    /etc/rc.d/init.d/heartbeat stop

    すべてのサービスが、1分以内にバックアップ・マシンに現れるはずです。バックアップ・マシンで /var/log/ha-logファイルをチェックし、また ps コマンドを使うと、LoadLevelerがバックアップ・マシンで実行していることが確認できます。バックアップ・マシンが制御を引き継いだら、バックアップ・マシンでユーザー loadl として llstatus コマンドと llq コマンドを実行します。図4と図5は、これらの実行出力です。

    図4. フェールオーバー後の、ノードha2でのコマンドllqの出力
    Output of the command llq, on node ha2, after failover
    図5. job1を実行依頼後の、ノードha1でのコマンドllqの出力
    Output of the command llstatus, on node ha2, after failover

    図4と図5で、下記に注意してください。

    1. 上記ステップ6で実行依頼されたジョブに対応する2つを含めて、古い、完全に終了していないジョブのすべてがリストアップされています。これは、ジョブ情報がマシン・フェールオーバーが起きても生存していることを示しています。
    2. Scheddが今やha2マシンにある。
    3. Startdは相変わらずha3マシンでダウンしたままである。
  8. ha3マシンでデーモンを再開する:ha3 でユーザー loadl として下記のコマンドを実行し、開始したデーモンを ha3 マシンで再開します。
    llctl resume startd

    今度は ha3 マシンがジョブ実行用として使用できます。2つのジョブは実行状態になり、最終的に ha3 マシンで完了するはずです。ジョブの実行完了は、このジョブの2つのステップで作られた .outファイルを見ることで確認できます( ha3 マシンの/home/loadl/samplesディレクトリーにあります)。この実行では、job1.ha1.23.0.outとjob1.ha1.23.1.outという2つのファイルが見えるはずです。

  9. プライマリーでハートビート・サービスを再開する: これによって、LoadLevelerプロセスがセカンダリーでは停止し、プライマリーで開始するはずです。プライマリーはまた、クラスターIPも引き継ぐはずです。次のコマンドでハートビートを開始します。

    /etc/rc.d/init.d/heartbeat start

    プライマリー・スケジューリング・ノードのフェール前に実行依頼されたジョブが、バックアップ・マシンが制御を引き継いだ後で回復される様子が分かると思います(共有ディスクを使って行われています)。


中央マネージャーに高可用性を設定する

中央マネージャーをスケジューリング・マシンとして別ノード( ha4 )に置いておくのであれば、中央マネージャーに組み込みの高可用性機能を利用することができます。この構成を試すには、各マシンのコンフィギュレーション・ファイルで ha4 マシンを中央マネージャーとして設定します。

ネットワーク通信の問題や、ソフトウェア、ハードウェアのフェールによって、中央マネージャーが使用できなくなる場合があります。そうした場合、LoadLevelerクラスターにある他のマシンは、中央マネージャー・マシンがもはや動作していないと考えます。この状況への対策として、定義ファイルにある、1台あるいはそれ以上の代替中央マネージャーを割り当て、制御を引き継がせます。

次の定義ファイルの例は、マシン ha5 を代替中央マネージャーとして定義します。

ha5: type = machine
     central_manager = alt

もし、プライマリーの中央マネージャーがフェールすると、今度は代替中央マネージャーが中央マネージャーとなります。代替中央マネージャーが中央マネージャーになる場合、ジョブが失われることはありませんが、クラスター中の全マシンが新しい中央マネージャーにチェックインするには数分を要する可能性があります。そのため、ジョブ状態のクエリーは短時間、正しくない可能性があります。

代替中央マネージャーを定義する場合には、コンフィギュレーション・ファイルで次のキーワードを設定する必要があります。

CENTRAL_MANAGER_HEARTBEAT_INTERVAL = <amount of time in seconds>
CENTRAL_MANAGER_TIMEOUT = < the number of heartbeat intervals>

下記の例では、代替中央マネージャーは、インターバル2つ分を待つことになります(各インターバルは30秒です)。

CENTRAL_MANAGER_HEARTBEAT_INTERVAL = 30
CENTRAL_MANAGER_TIMEOUT = 2

中央マネージャー・マシンのフェールオーバーをテストする

フェールオーバーのテストは、 ha4 マシン上にある Loadl_negotiator と呼ばれる中央マネージャー・プロセスを停止させます。同じノードで中央マネージャー・デーモンが再開されてしまうのを防ぐために、 RESTARTS_PER_HOUR キーワードを0に設定する必要があります。これによって約1分後、中央マネージャーが、代替である ha5 で起動するようになります。


LoadLevelerを実行するマシンに高可用性を設定する

この設定は、スケジューリング・マシンに高可用性を設定するのと同じです。


まとめ

今回は、LoadLevelerに組み込まれている機能を使ってLoadLevelerクラスターで高可用性を実装する方法、またオープン・ソースのソフトウェアを使うことによって可用性をさらに高める方法を説明しました。第4回では、IBM WebSphere ® Application Serverでの高可用性の実装を検証する予定です。


謝辞

IBM LoadLevelerでの高可用性実装を調査してくださったWaiman Chanと、IBM LoadLevelerに関する技術的な指導をしてくださったLiana L. Fongに感謝致します。


ダウンロード

内容ファイル名サイズ
Sample code package for this series of articleshahbcode.tar.gz25 KB

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source
ArticleID=228545
ArticleTitle=Linuxでの高可用性ミドルウェア、第3回: IBM LoadLeveler
publish-date=02282005