レベル: 中級 Hidayatullah Shaikh (hshaikh@us.ibm.com), Senior Software Engineer, IBM
2005年 2月 28日
オンデマンド・ビジネスにおいて、マシンの負荷管理は非常に重要です。IBM
®
LoadLeveler
®
はジョブ管理システムであり、これを使うことによってジョブのプロセス要求と使用可能リソースを一致させ、より少ない時間で、より多くのジョブを実行できるようになります。今日では、ジョブ管理システムの稼働時間を最大限に維持することが次第に重要になってきています。ここではLoadLevelerに組み込みの高可用性機能を使ってLoadLevelerクラスターの高可用性を実現する方法、そしてオープン・ソースの高可用性ソフトウェアを使って、それをさらに強化する方法について学びます。
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
™
ha1
、
ha2
、
ha3
という3台のマシンにインストールする方法を説明します。これらのステップは、LoadLeveler
Installation Memoドキュメント(
参考文献
にリンクがあります)のChapter 4に示されている概略に基づくものです。
-
LoadLevelerに対するディレクトリーを次のように作成する
- ローカル・ディレクトリー: /var/loadl
- ホーム・ディレクトリー: /home/loadl
- リリース・ディレクトリー: /opt/ibmll/LoadL/full
-
中央マネージャー・マシンの名前:
ha
-
rootとしてログインする
-
loadlグループ名を作る
下記のコマンドで、全ノード上に、グループIDとして1000を持つloadlグループが作られます。
-
loadlユーザーIDを作る
下記のコマンドで、全ノード上に、ユーザーID、
loadlが作られます。
useradd c loadleveler_user -d /home/loadl -s /bin/bash \
-u 1000 g 1000 -m loadl
|
-
LoadLeveler RPMをインストールする
-
ライセンスRPM(
LLIMAGEDIRがインストールRPMSを含んでいます)をインストールする
cd $LLIMAGEDIR
rpm -Uvh LoadL-full-license-3.2.0.0-0.i386.rpm
|
- 他のRPMをインストールする。
cd /opt/ibmll/LoadL/sbin
./install_ll -y -d "$LLIMAGEDIR"
|
-
初期化スクリプトllinitを実行する
- ローカル・ディレクトリーを作る。
- 所有権を設定する。
chown loadl.loadl /var/loadl
|
- loadl IDに切り換える。
- 下記を入力して、カレント・ディレクトリーをリリース・ディレクトリーのbinサブディレクトリーに変更する。
cd /opt/ibmll/LoadL/full/bin
|
- LoadLevelerのhome、local、/tmpの各ディレクトリーで、書き込み権限があることを確認する。
-
下記に示すように
llinit
コマンドを入力する。
./llinit -local /var/loadl -release /opt/ibmll/LoadL/full -cm ha
|
高可用性のスケジューリング・マシン構成を作る
この設定では、以下のようになります。
-
マシン
ha1
はプライマリー・スケジューリング・マシンとして動作する。
-
マシン
ha2
は、スタンバイ・スケジューリング・マシンとして動作する。
-
マシン
ha3
は、ジョブ実行マシンとして動作する。
高可用性の構成では、
ha1
に必要なローカル・ファイルやディレクトリーは外部の共有ディスク・ストレージに置かれるため、スケジューラー・ノードがフェールした場合には、
ha2
で使えるようになります。この設定方法は次の通りです。
-
ノード
ha1
と
ha2
でrootとしてログインする。
-
共有ディスク(/ha)に次のディレクトリーを作る。
- /ha/loadl/execute
- /ha/loadl/spool
-
ノード
ha1
で次のコマンドを実行し、所有権を設定する。
chown loadl.loadl /ha/loadl/
chown loadl.loadl /ha/loadl/execute
chown loadl.loadl /ha/loadl/spool
|
-
ノード
ha1
と
ha2
で
loadlIDに切り換える。
-
ノード
ha1
で次のコマンドを実行し、共有ディレクトリーに適当なパーミッションを設定する。
chmod 0777 /ha/loadl/execute
chmod 775 /ha/loadl/spool
|
-
ノード
ha1
と
ha2
で、/var/loadlの下にあるexecuteディレクトリーとspoolディレクトリーを削除する
rm -rf /var/loadl/execute
rm rf /var/loadl/spool
|
-
ノード
ha1
と
ha2
で次のコマンドを使い、共有ディレクトリーへのシンボリック・リンクを作る。
ln -s /ha/loadl/execute /var/loadl/execute
ln -s /ha/loadl/spool /var/loadl/spool
|
-
マシンの定義ファイルを編集する。下記は、それぞれのノード上での(/home/loadlの下にある)LoadL_adminファイルのうち、関係のある部分を示したものです。
-
ha1
はプライマリー・スケジューリング・マシンとして、また中央マネージャーとして動作します。実稼働環境では、中央マネージャーとスケジューリング・デーモンは別々のマシンに置くことを推奨します。
...
ha1: type = machine
central_manager = true
schedd_host = true
ha3: type = machine
...
|
-
ha2は、バックアップのスケジューリング・マシン/中央マネージャーとして動作します。
...
ha2: type = machine
central_manager = true
schedd_host = true
ha3: type = machine
...
|
-
ha3
は、実行マシンとして動作します。
...
ha: type = machine
central_manager = true
schedd_host = true
ha3: type = machine
...
|
-
それぞれのマシンで、(/home/loadlの下にある)LoadL_configファイルにある
RUNS_HERE
フラグを次のように変更します。
-
ha1とha2
...
SCHEDD_RUNS_HERE = True
STARTD_RUNS_HERE = False
...
|
これによって、スケジューリング・マシンではジョブが実行されなくなります。つまり ha1 と ha2
を、スケジューリング・マシンとしてのみ動作するようにするのです。
-
ha3
...
SCHEDD_RUNS_HERE = False
STARTD_RUNS_HERE = True
...
|
-
3つのノード上の/etc/hostsファイルを次のように編集します。
-
ha1
...
9.22.7.46 ha.haw2.ibm.com ha
9.22.7.46 ha2.haw2.ibm.com ha2
...
|
-
ha2
...
9.22.7.46 ha.haw2.ibm.com ha
9.22.7.46 ha1.haw2.ibm.com ha1
...
|
-
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を管理するように、ハートビートを下記のように設定します。
-
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 |
-
今度は(両方のスケジューリング・マシンにある)/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を解放します。

 |
スケジューリング・マシンのフェールオーバーのテスト
このセクションでは、スケジューリング・デーモンの高可用性のテスト方法を説明します。
-
ハートビートを開始する:
プライマリー・ノードで、次にバックアップ・ノードで、次のコマンドを使ってハートビート・サービスを開始します。
/etc/rc.d/init.d/heartbeat start
|
ハートビートが問題なく起動すると、ha.cfファイルで設定したIPアドレスを持った、新しいインターフェースが見えるはずです。一旦ハートビートが起動したら、プライマリーでログ・ファイル(デフォルトは /var/log/ha-log)を覗き、IPの引き継ぎを行ってからLoadLevelerを起動していることを確認します。
ps
コマンドを使って、LoadLevelerデーモンがプライマリー・ノードで実行していることを確認します。バックアップ・ノードでは、ハートビートが上記のプロセスを起動することはありません。それが起きるのは、プライマリーがフェールした後のみです。
-
Loadlevelerデーモンを開始する:
次のコマンドを使い、ユーザー
loadl として、ha3
でloadlevelerデーモンを開始します。
-
ha3を使用不可にする:
startd
デーモンを排出状態にすることにより、実行マシンとしてha3を使用不可にします。これは、ジョブを実行依頼した後、フェールオーバーのテストに充分な時間を与えるために必要です。ノードha3
でユーザー
loadl
として、下記のコマンドを使います。
- LoadLevelerクラスターでどんなジョブがスケジュールされているかを、
ha1
マシンでユーザー
loadl
として下記のコマンドを使って調べます。
この設定でのコマンド出力を図1に示します。このコマンドは、LoadLevelerクラスター上にあった、古い、完全に終了していないジョブを全てリストアップします。
図1. ノードha1でのコマンドllqの出力
ha1マシンでユーザーloadlとして下記のコマンドを実行し、LoadLevelerクラスター上のマシンの状態を調べます。
図2. ノードha1でのコマンドllstatusの出力
図2を見ると、ha1マシンにScehddがあることが分かります。また上記のステップ3により、ha3マシンでStartdが排出状態にされていることが分かります。
-
samplesディレクトリーの所有権を設定する:ノードha3
(ここでジョブが実行されます)で下記のコマンドを使ってサンプル・ディレクトリーの所有権を設定します。
chown loadl.loadl /opt/ibmll/LoadL/full/samples
|
-
ジョブを実行依頼する:
マシン
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の出力
では、プライマリー・スケジューリング・マシンをフェールさせましょう。
-
フェールオーバーをシミュレートする:
これは単に下記のコマンドを使って、プライマリー・システムでハートビートを停止するだけです。
/etc/rc.d/init.d/heartbeat stop
|
すべてのサービスが、1分以内にバックアップ・マシンに現れるはずです。バックアップ・マシンで
/var/log/ha-logファイルをチェックし、また
ps
コマンドを使うと、LoadLevelerがバックアップ・マシンで実行していることが確認できます。バックアップ・マシンが制御を引き継いだら、バックアップ・マシンでユーザー
loadl
として
llstatus
コマンドと
llq
コマンドを実行します。図4と図5は、これらの実行出力です。
図4. フェールオーバー後の、ノードha2でのコマンドllqの出力
図5. job1を実行依頼後の、ノードha1でのコマンドllqの出力
図4と図5で、下記に注意してください。
-
上記ステップ6で実行依頼されたジョブに対応する2つを含めて、古い、完全に終了していないジョブのすべてがリストアップされています。これは、ジョブ情報がマシン・フェールオーバーが起きても生存していることを示しています。
- Scheddが今やha2マシンにある。
- Startdは相変わらずha3マシンでダウンしたままである。
-
ha3マシンでデーモンを再開する:
ha3
でユーザー
loadl
として下記のコマンドを実行し、開始したデーモンを
ha3
マシンで再開します。
今度は
ha3
マシンがジョブ実行用として使用できます。2つのジョブは実行状態になり、最終的に
ha3
マシンで完了するはずです。ジョブの実行完了は、このジョブの2つのステップで作られた
.outファイルを見ることで確認できます(
ha3
マシンの/home/loadl/samplesディレクトリーにあります)。この実行では、job1.ha1.23.0.outとjob1.ha1.23.1.outという2つのファイルが見えるはずです。
-
プライマリーでハートビート・サービスを再開する:
これによって、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 articles | hahbcode.tar.gz | 25 KB |
FTP |
|---|
参考文献
著者について  | |  | Hidayatullah H. ShaikhはIBM T.J. Watson Research Centerのオンデマンド・アーキテクチャーと開発チームのシニア・ソフトウェア技術者です。関心領域は広く、ビジネス・プロセスのモデル化と統合、サービス指向アーキテクチャー、グリッド・コンピューティング、eコマース、エンタープライズJava、データベース管理システム、それに高可用性クラスターに渡っています。連絡先はhshaikh@us.ibm.comです。 |
記事の評価
|