インフラエンジニアのためのHadoop情報 目次 [Hadoop]
インフラエンジニアのためのHadoop情報
・構築編
・運用編
・障害対応
・監視
・その他
・構築編
Hadoopインストール
動かしてみる
クラスタ構築その1
クラスタ構築その2
・運用編
SecondaryNameNode
NameNodeバックアップ
DataNodeの追加
DataNodeの取り外し
ログの切捨て
・障害対応
障害復旧その1
障害復旧その2
障害復旧のために
・監視
状態監視その1
状態監視その2
Gangliaその1
Gangliaその2
・その他
PuppetとHadoop
CDH2のアップデート
インフラエンジニアのためのHadoop情報 ログの切捨て [Hadoop]
Hadoopはlog4jを使って、大量のログを生成しています。連日ジョブを走らせている
ような環境では、NameNodeのログ領域はGバイト単位で肥大化してディスクを圧迫します。
ログの出力ディレクトリをシステム領域と共有している場合などは、ディスク残容量
不足でシステムトラブルの原因にもなりえます。
見落としがちですが、ログの管理もやっておきましょう。
ローテーションについては、Hadoopがやってくれているので、不要なログを抑制して
不要になった古いログは削除するようにします。
ログの抑制についてですが、CDHを使う限りHDFSへのアクセスにパーミッションを設定して
はいないので、HDFSへの監査ログは不要と思われます。
しかも、この監査ログがHDFSへのアクセスの度に記録されるので、肥大化の原因になって
ます。
log4j.properties中に定義されている「SNamesystem Audit logging」をデフォルトの
INFO(全て)からWARNに切り替えます。
以下の行をlog4j.propertiesに追加します。
ちなみに、log4j.propertiesのコメント中には、
の記述がありますが、これを設定してもログに変化は見られませんでした。
次に、古いログを削除しましょう。
例えば、以下のようなスクリプトを/etc/cron.dailyに作成しておき、指定した日にちが
経過したログは削除するようにします。
ような環境では、NameNodeのログ領域はGバイト単位で肥大化してディスクを圧迫します。
ログの出力ディレクトリをシステム領域と共有している場合などは、ディスク残容量
不足でシステムトラブルの原因にもなりえます。
見落としがちですが、ログの管理もやっておきましょう。
ローテーションについては、Hadoopがやってくれているので、不要なログを抑制して
不要になった古いログは削除するようにします。
ログの抑制についてですが、CDHを使う限りHDFSへのアクセスにパーミッションを設定して
はいないので、HDFSへの監査ログは不要と思われます。
しかも、この監査ログがHDFSへのアクセスの度に記録されるので、肥大化の原因になって
ます。
log4j.properties中に定義されている「SNamesystem Audit logging」をデフォルトの
INFO(全て)からWARNに切り替えます。
以下の行をlog4j.propertiesに追加します。
log4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=WARN
ちなみに、log4j.propertiesのコメント中には、
#log4j.logger.org.apache.hadoop.fs.FSNamesystem.audit=WARN
の記述がありますが、これを設定してもログに変化は見られませんでした。
次に、古いログを削除しましょう。
例えば、以下のようなスクリプトを/etc/cron.dailyに作成しておき、指定した日にちが
経過したログは削除するようにします。
#!/bin/bash # 15日前のHadoopログを削除する。 CDATE=15 LOGS=/var/log/hadoop-0.20 /bin/rm -r `find $LOGS -ctime +$CDATE`
インフラエンジニアのためのHadoop情報 CDH2のアップデート [Hadoop]
Cloudera版のCDH2パッケージは、不定期にマイナーバージョンアップをしているようです。
ここでは、CDH2のバージョンアップ方法について書いておきます。
但し、HDFSのレイアウト変更を伴うようなメジャーバージョンのアップについては、それぞれ
の版ごとに注意事項があるはずなので、それらについてはここでは触れません。
Hadoopのアップデートで気をつけなければいけない点は、以下のとおり。
複数ノードで運用中、1台づつアップグレードすることができません。たとえマイナーバージョンアップといえども、NameNodeとDataNodeの間でバージョン番号のチェックが行われて、アップデートしたノードは古いバージョン
のクラスタに登録できないからです。
もう一点は、一度新しいバージョンでサービスを起動すると、たとえHadoopサービスを前の
バージョンに戻しても、起動しなくなります。新しいバージョンの起動時にローカルのデータ
ストアにバージョン番号が書き込まれているようです。
そういう理由で、バージョンアップはクラスタ全体を停止して、いっぺんに全てのノードを
アップデートする必要があります。
きちんと計画的に実施しましょう。
作業の前には、fsckコマンドを実施してHDFSが健全な状態であることを確認します。
Hadoopの全ノードを停止します。
停止順は、NameNode、JobTracker、DataNode、TaskTracker、SecondaryNameNodeです。
サービスの停止が確認できたら、yumコマンドでアップデートを実施します。
無事バージョンがあがっているこを確認します。(必ず起動前に)
全てのノードでアップデートが完了したら、全ノードを起動します。
起動順は、停止順と同じです。
ここでは、CDH2のバージョンアップ方法について書いておきます。
但し、HDFSのレイアウト変更を伴うようなメジャーバージョンのアップについては、それぞれ
の版ごとに注意事項があるはずなので、それらについてはここでは触れません。
Hadoopのアップデートで気をつけなければいけない点は、以下のとおり。
複数ノードで運用中、1台づつアップグレードすることができません。たとえマイナーバージョンアップといえども、NameNodeとDataNodeの間でバージョン番号のチェックが行われて、アップデートしたノードは古いバージョン
のクラスタに登録できないからです。
もう一点は、一度新しいバージョンでサービスを起動すると、たとえHadoopサービスを前の
バージョンに戻しても、起動しなくなります。新しいバージョンの起動時にローカルのデータ
ストアにバージョン番号が書き込まれているようです。
そういう理由で、バージョンアップはクラスタ全体を停止して、いっぺんに全てのノードを
アップデートする必要があります。
きちんと計画的に実施しましょう。
作業の前には、fsckコマンドを実施してHDFSが健全な状態であることを確認します。
$ hadoop fsck / : The filesystem under path '/' is HEALTHY
Hadoopの全ノードを停止します。
停止順は、NameNode、JobTracker、DataNode、TaskTracker、SecondaryNameNodeです。
サービスの停止が確認できたら、yumコマンドでアップデートを実施します。
$ sudo yum install hadoop : ================================================= ====================================== Package Arch Version Repository Size ================================================= ====================================== Updating: hadoop-0.20 noarch 0.20.1+169.113-1 cloudera-cdh2 21 M Updating for dependencies: hadoop-0.20-conf-pseudo noarch 0.20.1+169.113-1 cloudera-cdh2 10 k Transaction Summary ================================================= ====================================== Install 0 Package(s) Upgrade 2 Package(s) Total download size: 21 M Is this ok [y/N]: y
無事バージョンがあがっているこを確認します。(必ず起動前に)
$ hadoop version Hadoop 0.20.1+169.113 Subversion -r 6c765a47a9291470d3d8814c98155115d109d715 Compiled by root on Sun Sep 12 01:29:03 EDT 2010
全てのノードでアップデートが完了したら、全ノードを起動します。
起動順は、停止順と同じです。
インフラエンジニアのためのHadoop情報 PuppetとHadoop [Hadoop]
Hadoopでは、各ノードの設定ファイルを基本的に同一にしておく必要があります。
(ローカル特有な設定は除く)
クラスタに係わる設定を変更したい時は、全てのノードの設定ファイルを変更しなければ
いけないので、大変です。
しかも、Cloudera版Hadoopは全てのノードのサービスを再起動する必要もあります。
Hadoopクラスタ内のどこか1台をマスタにして、他のホストと設定を同期するようにしましょう。使用するのは、システム管理ツールとして知られるPuppet。
Puppetのインストールと基本設定については、
http://gihyo.jp/admin/serial/01/puppet
に詳しく紹介されているので、参考にしてインストールします。
ここでは、Hadoopの設定ファイル同期について紹介します。
puppetにはpushモードとpullモードがあります。
pullモードは、各ノードが30分おきにサーバへ同期をとりにいきます。
Hadoopの設定ファイルをそんなに頻繁に書き換えることは無いだろうし、再起動のからみも
あるので、ここはpushモードにします。
マスタとしてインストールしたPuppetのあるノードで、Hadoopの設定ファイルを書き換えたら
その都度、手動でpuppetrunコマンドで同期します。
site.ppの設定は、
fileserver.confには、
allowの指定にはワイルドカードが使えるので、全ノードを指定します。
同期される側の各ノードの設定は、namespaceauth.confに
とします。
各ノード側のPuppetの起動時には、puppetrun待ちのオプション「--listen --no-client」を
付けます。
例)
Hadoopの設定ファイルを更新後、同期を実施するには
とすれば、マスタサーバでの変更がノードの設定ファイルにも反映されます。
このままでは、設定ファイルが書き換わるだけで、再起動をしていないノードのHadoopには反映
されません。
そこで、同期と同時にノード側のHadoopサービスを再起動させましょう。
site.ppに以下の設定を追加します。
こうすると、設定ファイルのあるディレクトリ以下のファイルが更新されていたらDataNodeと
TaskTrackerのサービスが再起動されます。
実際の運用を想定したサンプルを以下に置いておきます。
https://github.com/so-net-developer/Hadoop/tree/master/puppet/
Puppet自身を含めた設定ファイルの同期と、サービスの再起動、ノードの追加が自動化されます。
(ローカル特有な設定は除く)
クラスタに係わる設定を変更したい時は、全てのノードの設定ファイルを変更しなければ
いけないので、大変です。
しかも、Cloudera版Hadoopは全てのノードのサービスを再起動する必要もあります。
Hadoopクラスタ内のどこか1台をマスタにして、他のホストと設定を同期するようにしましょう。使用するのは、システム管理ツールとして知られるPuppet。
Puppetのインストールと基本設定については、
http://gihyo.jp/admin/serial/01/puppet
に詳しく紹介されているので、参考にしてインストールします。
ここでは、Hadoopの設定ファイル同期について紹介します。
puppetにはpushモードとpullモードがあります。
pullモードは、各ノードが30分おきにサーバへ同期をとりにいきます。
Hadoopの設定ファイルをそんなに頻繁に書き換えることは無いだろうし、再起動のからみも
あるので、ここはpushモードにします。
マスタとしてインストールしたPuppetのあるノードで、Hadoopの設定ファイルを書き換えたら
その都度、手動でpuppetrunコマンドで同期します。
site.ppの設定は、
$path = '/etc/hadoop-0.20/conf.cluster' file { $path: source => 'puppet://srv1.example.com/hadoop/conf.cluster', recurse => true, }
fileserver.confには、
[hadoop] path /etc/hadoop-0.20 allow [Hadoopノードのアドレス]
allowの指定にはワイルドカードが使えるので、全ノードを指定します。
同期される側の各ノードの設定は、namespaceauth.confに
[puppetrunner] allow [マスタサーバのアドレス]
とします。
各ノード側のPuppetの起動時には、puppetrun待ちのオプション「--listen --no-client」を
付けます。
例)
$ /usr/sbin/puppetd --server [マスタサーバのアドレス] --listen --no-client
Hadoopの設定ファイルを更新後、同期を実施するには
$ sudo /usr/bin/puppetrun --host [Hadoopノードのアドレス]
とすれば、マスタサーバでの変更がノードの設定ファイルにも反映されます。
このままでは、設定ファイルが書き換わるだけで、再起動をしていないノードのHadoopには反映
されません。
そこで、同期と同時にノード側のHadoopサービスを再起動させましょう。
site.ppに以下の設定を追加します。
exec { '/etc/init.d/hadoop-0.20-datanode restart': subscribe => File['/etc/hadoop-0.20/conf.cluster'], refreshonly => true } exec { '/etc/init.d/hadoop-0.20-tasktracker restart': subscribe => File['/etc/hadoop-0.20/conf.cluster'], refreshonly => true }
こうすると、設定ファイルのあるディレクトリ以下のファイルが更新されていたらDataNodeと
TaskTrackerのサービスが再起動されます。
実際の運用を想定したサンプルを以下に置いておきます。
https://github.com/so-net-developer/Hadoop/tree/master/puppet/
Puppet自身を含めた設定ファイルの同期と、サービスの再起動、ノードの追加が自動化されます。
インフラエンジニアのためのHadoop情報 Gangliaその2 [Hadoop]
Hadoopノード側のGangliaのインストールです。JMXメタデータを採取する側です。
ライブラリのインストール。
前回作ったrpmパッケージをインストール。
起動スクリプトは、監視サーバのものをコピー。
設定ファイルも監視サーバのものをコピー。
起動します。
Gangliaはデフォルトではマルチキャストで監視側と通信するので、Ganglia監視サーバ
が同一セグメントにいれば、これでノード側のサーバ情報はグラフで見れるようになる
はずです。
無事動いたところで、本題のHadoopのJMXデータを拾います。
Cloudera版のHadoopは設定ファイル「hadoop-metrics.properties」の中にGangliaContext
が定義されています。今回は、ganglia-3.1.7なので、GangliaContext31を有効にします。
サービスを再起動します。
しばらくすると、gangliaの画面にJMXの情報が表示されます。
ライブラリのインストール。
$ sudo yum install libconfuse $ sudo yum install rrdtool
前回作ったrpmパッケージをインストール。
$ sudo rpm -ivh ganglia-3.1.7-1.i386.rpm
起動スクリプトは、監視サーバのものをコピー。
$ sudo cp gmond /etc/init.d/
設定ファイルも監視サーバのものをコピー。
$ cp gmond.conf /etc/ganglia/
起動します。
$ sudo /sbin/service gmond start
Gangliaはデフォルトではマルチキャストで監視側と通信するので、Ganglia監視サーバ
が同一セグメントにいれば、これでノード側のサーバ情報はグラフで見れるようになる
はずです。
無事動いたところで、本題のHadoopのJMXデータを拾います。
Cloudera版のHadoopは設定ファイル「hadoop-metrics.properties」の中にGangliaContext
が定義されています。今回は、ganglia-3.1.7なので、GangliaContext31を有効にします。
dfs.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 dfs.period=10 dfs.servers=[Ganglia監視側ホストのIP]:8649 mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 mapred.period=10 mapred.servers=[Ganglia監視側ホストのIP]:8649 jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 jvm.period=10 jvm.servers=[Ganglia監視側ホストのIP]:8649
サービスを再起動します。
$ sudo /sbin/service hadoop-0.20-datanode restart $ sudo /sbin/service hadoop-0.02-tasktracker restart
しばらくすると、gangliaの画面にJMXの情報が表示されます。
インフラエンジニアのためのHadoop情報 Gangliaその1 [Hadoop]
これまではHadoopの死活監視が目的のNagios設定を見てきましたが、HadoopはJMX
を通してメモリ使用状況、ジョブ(MapReduce)の進行状況を詳細に見ることができます。
このJMXの値を、Gangliaというグラフ表示の監視ツールを使って可視化しましょう。
ジョブの投入状況に合わせて、メモリやCPUの利用率が各ノード毎にグラフ化されて
見えるので、ボトルネックの発見に役立つはずです。
Gangliaのインストールは終わっているものとして・・・としたいところですが
Nagiosと違って、Hadoopの各ノード側全てにインストールしなければいけないので
ちょっと面倒。
rpmパッケージを作って、各ノードに配布しちゃいましょう。
まずは、Ganglia監視サーバ側を作成。
rpm化にはcheckinstallを使います。あらかじめインストールしておきます。
ビルドに必要なものを片っ端からインストール。
次にGangliaのサイトから「ganglia-3.1.7.tar.gz」を取得してきてビルド。
出来上がった「ganglia-3.1.7-1.i386.rpm」をインストール。
このあと、設定ファイル、作業ディレクトリ作成、パーミッション設定、起動スクリプト作成
その他いろいろしないと起動しないのですが、これらもrpm化したパッケージを作ったので
それで早道しちゃいます。
http://github.com/so-net-developer/Hadoop/blob/master/tools/ganglia-conf-1.0-0.noarch.rpm
rpm化に使ったSPECファイルも置いておくので、何をやっているかはこれを見てください。
http://github.com/so-net-developer/Hadoop/blob/master/tools/ganglia-conf-1.0.spec
Ganglia監視サーバの起動。
参考までに、SPECファイルを使ってganglia-conf-1.0-0.noarch.rpmを作る方法を書いて
おきます。
まず、下に示すようなディレクトリを作り、ファイルを配置します。設定ファイルや起動
スクリプトもgangliaのソースを展開すると見つかるので、環境に合わせて修正したものを
配置します。
そして、homeディレクトリに上に示したrpmディレクトリを示すファイル「.rpmmacros」
を作ります。
そして、以下のようにtarファイルをSOURCES以下に作成します。
最後にrpmbuildコマンドでspecファイルを指定すればrpm/RPMS以下にrpmファイルが作られます。
次回は、Hadoopノード側のインストール。
を通してメモリ使用状況、ジョブ(MapReduce)の進行状況を詳細に見ることができます。
このJMXの値を、Gangliaというグラフ表示の監視ツールを使って可視化しましょう。
ジョブの投入状況に合わせて、メモリやCPUの利用率が各ノード毎にグラフ化されて
見えるので、ボトルネックの発見に役立つはずです。
Gangliaのインストールは終わっているものとして・・・としたいところですが
Nagiosと違って、Hadoopの各ノード側全てにインストールしなければいけないので
ちょっと面倒。
rpmパッケージを作って、各ノードに配布しちゃいましょう。
まずは、Ganglia監視サーバ側を作成。
rpm化にはcheckinstallを使います。あらかじめインストールしておきます。
ビルドに必要なものを片っ端からインストール。
$ sudo yum install rpm-build $ sudo yum install checkinstall $ sudo yum install libconfuse $ sudo yum install libconfuse-devel $ sudo yum install rrdtool $ sudo yum install rrdtool-devel $ sudo yum install gcc $ sudo yum install apr-devel $ sudo yum install expat-devel $ sudo yum install pcre-devel $ sudo yum install php $ sudo yum install php-gd $ sudo yum install httpd
次にGangliaのサイトから「ganglia-3.1.7.tar.gz」を取得してきてビルド。
$ tar xvf ganglia-3.1.7.tar.gz $ cd ganglia-3.1.7 $ ./configure --with-gmetad --sysconfdir=/etc/ganglia $ make $ sudo /usr/sbin/checkinstall
出来上がった「ganglia-3.1.7-1.i386.rpm」をインストール。
$ sudo rpm -ivh ganglia-3.1.7-1.i386.rpm
このあと、設定ファイル、作業ディレクトリ作成、パーミッション設定、起動スクリプト作成
その他いろいろしないと起動しないのですが、これらもrpm化したパッケージを作ったので
それで早道しちゃいます。
http://github.com/so-net-developer/Hadoop/blob/master/tools/ganglia-conf-1.0-0.noarch.rpm
rpm化に使ったSPECファイルも置いておくので、何をやっているかはこれを見てください。
http://github.com/so-net-developer/Hadoop/blob/master/tools/ganglia-conf-1.0.spec
$ sudo rpm -ivh ganglia-conf-1.0-0.noarch.rpm
Ganglia監視サーバの起動。
$ sudo /sbin/service gmetad start $ sudo /sbin/service gmond start $ sudo /sbin/service httpd start
参考までに、SPECファイルを使ってganglia-conf-1.0-0.noarch.rpmを作る方法を書いて
おきます。
まず、下に示すようなディレクトリを作り、ファイルを配置します。設定ファイルや起動
スクリプトもgangliaのソースを展開すると見つかるので、環境に合わせて修正したものを
配置します。
|-- ganglia-conf-1.0 | |-- etc | | |-- ganglia ←ganglia(gmond)用設定ファイル | | | `-- gmond.conf | | `-- init.d ←gangliaの起動スクリプト | | |-- gmetad | | `-- gmond | `-- var | `-- www | `-- html | `-- ganglia ←gangliaのソース中にあるwebディレクトリ以下全部 | |-- index.php | |-- 省略 | `-- version.php.in `-- rpm |-- BUILD |-- RPMS |-- SOURCES |-- SPECS | `-- ganglia-conf-1.0.spec `-- SRPMS
そして、homeディレクトリに上に示したrpmディレクトリを示すファイル「.rpmmacros」
を作ります。
$ echo "%_topdir /home/so-net/rpm" > .rpmmacros
そして、以下のようにtarファイルをSOURCES以下に作成します。
$ tar czvf rpm/SOURCES/ganglia-conf-1.0.tar.gz ganglia-conf-1.0
最後にrpmbuildコマンドでspecファイルを指定すればrpm/RPMS以下にrpmファイルが作られます。
$ rpmbuild -ba rpm/SPECS/ganglia-conf-1.0.spec
次回は、Hadoopノード側のインストール。
インフラエンジニアのためのHadoop情報 状態監視その2 [Hadoop]
TaskTrackerもDataNodeと同じように監視できます。
JobTrackerのWebUI(http://[JobTrackerのIP]:50030/jobtracker.jsp)画面中に表示されている
TaskTrackerのノード数を確認することで監視を行います。
チェックプログラムはこちら。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hadoop-task.pl
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-tasktrackers/details
commands.cfgはこうなる。
ARG1、ARG2はDataNodeのときと同じ。
services.cfgの例は
SecondaryNameNodeの稼動状況の確認は、ステータスを確認する機能が見当たらないので、
メタデータファイルの更新状況を確認して判断します。
ファイルの更新は、SecondaryNameNode内で行われるので、Nagiosサーバからそれを直接見に
いくことができません。そこでNagios用nrpeの登場です。
監視対象のSecondaryNameNode側にnrpeを設定してNagiosサーバに通知してもらいます。
SecondaryNameNodeへのnrpeのインストール、基本設定は済ませてください。
メタデータファイルの更新状況を確認するスクリプトを以下に挙げておきます。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/secondarynamenode_check.sh
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-secondarynamenode/details
120分以上更新されていないファイルが見つかったら、SecondaryNameNodeのチェックポイントに
異常が発生しているとみなして、アラートを発します。
SecondaryNameNode上のnrpeの設定ファイルnrpe.cfgに以下の行を追加する。
そして、Nagios側のcommands.cfgはこうなる。
ARG1には、nrpeコマンドの識別子「check_checkpoint」を代入するので、services.cfgの例は
Nagios監視の最後にHadoopのHDFSについてです。HadoopのHDFSは、付属ツールの
「hadoop fsck」コマンドを実行すると、HDFSブロックの整合性やレプリケーションの状態、
DataNode数などが表示されます。
実行例)
最後の行に、「HEALTHY」と出てくると安心します。
どうせだから、これもNagiosで監視してしまいましょう。
nrpeでコマンドを起動し、「HEALTHY」が表示されなければ、アラートをあげるようにします。
nrpeでfsckコマンドを起動して、「HEALTHY」表示を確認するチェックスクリプトはこちら。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hdfs.sh
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-HDFS-healthy/details
(hadoopコマンドにパスが通っていること、HDFSブロック数が非常に多いとnrpeのタイムアウトに注意)
nrpeはPrimaryNameNodeで動かします。(そこでしかfsckが通らないから)
nrpeの設定ファイルnrpe.cfgに以下を追加。
Nagiosサーバ側の設定もいつものように。
commands.cfg
services.cfg
JobTrackerのWebUI(http://[JobTrackerのIP]:50030/jobtracker.jsp)画面中に表示されている
TaskTrackerのノード数を確認することで監視を行います。
チェックプログラムはこちら。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hadoop-task.pl
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-tasktrackers/details
commands.cfgはこうなる。
define command { command_name check_remote_tasktracker command_line /usr/local/bin/check_hadoop-task.pl $HOSTADDRESS$ $ARG1$ $ARG2$ }
ARG1、ARG2はDataNodeのときと同じ。
services.cfgの例は
define service { use generic-service host_name [JobTrackerホスト名] service_description check_remote_tasktracker contact_groups admins check_command check_remote_tasktracker!15!13 }
SecondaryNameNodeの稼動状況の確認は、ステータスを確認する機能が見当たらないので、
メタデータファイルの更新状況を確認して判断します。
ファイルの更新は、SecondaryNameNode内で行われるので、Nagiosサーバからそれを直接見に
いくことができません。そこでNagios用nrpeの登場です。
監視対象のSecondaryNameNode側にnrpeを設定してNagiosサーバに通知してもらいます。
SecondaryNameNodeへのnrpeのインストール、基本設定は済ませてください。
メタデータファイルの更新状況を確認するスクリプトを以下に挙げておきます。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/secondarynamenode_check.sh
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-secondarynamenode/details
120分以上更新されていないファイルが見つかったら、SecondaryNameNodeのチェックポイントに
異常が発生しているとみなして、アラートを発します。
SecondaryNameNode上のnrpeの設定ファイルnrpe.cfgに以下の行を追加する。
command[check_checkpoint]=/usr/local/bin/secondarynamenode_check.sh
そして、Nagios側のcommands.cfgはこうなる。
define command { command_name check_nrpe_secondarynamenode command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ }
ARG1には、nrpeコマンドの識別子「check_checkpoint」を代入するので、services.cfgの例は
define service { use generic-service host_name sdh02 service_description check_nrpe_secondarynamenode contact_groups admins check_command check_nrpe_secondarynamenode!check_checkpoint }
Nagios監視の最後にHadoopのHDFSについてです。HadoopのHDFSは、付属ツールの
「hadoop fsck」コマンドを実行すると、HDFSブロックの整合性やレプリケーションの状態、
DataNode数などが表示されます。
実行例)
$ hadoop fsck / Total size: 2235588327935 B Total dirs: 127 Total files: 454 Total blocks (validated): 33584 (avg. block size 66567065 B) Minimally replicated blocks: 33584 (100.0 %) Over-replicated blocks: 0 (0.0 %) Under-replicated blocks: 0 (0.0 %) Mis-replicated blocks: 0 (0.0 %) Default replication factor: 3 Average block replication: 3.001608 Corrupt blocks: 0 Missing replicas: 0 (0.0 %) Number of data-nodes: 16 Number of racks: 1 The filesystem under path '/' is HEALTHY
最後の行に、「HEALTHY」と出てくると安心します。
どうせだから、これもNagiosで監視してしまいましょう。
nrpeでコマンドを起動し、「HEALTHY」が表示されなければ、アラートをあげるようにします。
nrpeでfsckコマンドを起動して、「HEALTHY」表示を確認するチェックスクリプトはこちら。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hdfs.sh
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-HDFS-healthy/details
(hadoopコマンドにパスが通っていること、HDFSブロック数が非常に多いとnrpeのタイムアウトに注意)
nrpeはPrimaryNameNodeで動かします。(そこでしかfsckが通らないから)
nrpeの設定ファイルnrpe.cfgに以下を追加。
command[check_hdfs]=/usr/local/bin/check_hdfs.sh
Nagiosサーバ側の設定もいつものように。
commands.cfg
define command { command_name check_nrpe_hdfs command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -t 30 }
services.cfg
define service { use generic-service host_name sdh01 service_description check_nrpe_hdfs contact_groups admins check_command check_nrpe_hdfs!check_hdfs }
インフラエンジニアのためのHadoop情報 状態監視その1 [Hadoop]
Hadoopを運用するノードもそれなりの台数になってくると、ノードの稼動状態を監視する
必要が出てきます。10台以上にもなるとそれぞれにログインしてプロセスを確認するのも
かなり面倒です。
ここでは、監視ツールとしてポピュラーな「Nagios」を使って、Hadoopノードを監視する
方法について書いておきます。
使うのは「check_http」コマンドです。このコマンドは、指定ポートに接続してhttpを
getして、得られるレスポンス文字列を調べて状態を判定します。
これを使ってHadoopの各サービスの状態を見てみましょう。
NameNode用のWebUI(http://[NameNodeのIP]:50070/dfshealth.jsp)には、レスポンス中に
「NameNode」の文字列が入っています。
この文字列を取得できたら、少なくともNameNodeは止まってはいないと判断できます。
このチェックを実現するNagiosのcommands.cfgの設定は以下のようになります。
引数ARG1にはポート番号50070が入るので、service.cfgは以下のようになる。
JobTrackerも同じようにチェックできます。こちらは、「Map/Reduce」という文字列をチェック。
DataNodeを監視したい場合は、各ノードにはWebUIが無いので、NameNodeの
WebUI(http://[NameNodeのIP]:50070/dfshealth.jsp)の画面から、稼動中の台数を示す文字列を
拾ってチェックします。
チェックプログラムはこちら。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hadoop-dfs.pl
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-datanodes/details
commands.cfgはこうなる。
ARG1、ARG2にはDataNodeの台数を指定し、それぞれ指定台数を下回る(ノード停止)と
「WARNING」、「CRITICAL」のアラートを発生する。
services.cfgの例は
となり、この場合は稼動しているDataNodeの台数が15台以下になると「WARNING」アラートが、
13台以下になると、「CRITICAL」アラートが出る。
必要が出てきます。10台以上にもなるとそれぞれにログインしてプロセスを確認するのも
かなり面倒です。
ここでは、監視ツールとしてポピュラーな「Nagios」を使って、Hadoopノードを監視する
方法について書いておきます。
使うのは「check_http」コマンドです。このコマンドは、指定ポートに接続してhttpを
getして、得られるレスポンス文字列を調べて状態を判定します。
これを使ってHadoopの各サービスの状態を見てみましょう。
NameNode用のWebUI(http://[NameNodeのIP]:50070/dfshealth.jsp)には、レスポンス中に
「NameNode」の文字列が入っています。
この文字列を取得できたら、少なくともNameNodeは止まってはいないと判断できます。
このチェックを実現するNagiosのcommands.cfgの設定は以下のようになります。
define command { command_name check_remote_namenode command_line $USER1$/check_http -H $HOSTADDRESS$ -u http://$HOSTADDRESS$:$ARG1$/dfshealth.jsp -p $ARG1$ -r NameNode }
引数ARG1にはポート番号50070が入るので、service.cfgは以下のようになる。
define service { use generic-service host_name [NameNodeホスト名] service_description check_remote_namenode contact_groups admins check_command check_remote_namenode!50070 }
JobTrackerも同じようにチェックできます。こちらは、「Map/Reduce」という文字列をチェック。
define command { command_name check_remote_jobtracker command_line $USER1$/check_http -H $HOSTADDRESS$ -u http://$HOSTADDRESS$:$ARG1$/jobtracker.jsp -p $ARG1$ -r Map/Reduce }
define service { use generic-service host_name [JobTrackerホスト名] service_description check_remote_jobtracker contact_groups admins check_command check_remote_jobtracker!50030 }
DataNodeを監視したい場合は、各ノードにはWebUIが無いので、NameNodeの
WebUI(http://[NameNodeのIP]:50070/dfshealth.jsp)の画面から、稼動中の台数を示す文字列を
拾ってチェックします。
チェックプログラムはこちら。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hadoop-dfs.pl
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-datanodes/details
commands.cfgはこうなる。
define command { command_name check_remote_datanode command_line /usr/local/bin/check_hadoop-dfs.pl $HOSTADDRESS$ $ARG1$ $ARG2$ }
ARG1、ARG2にはDataNodeの台数を指定し、それぞれ指定台数を下回る(ノード停止)と
「WARNING」、「CRITICAL」のアラートを発生する。
services.cfgの例は
define service { use generic-service host_name [NameNodeホスト名] service_description check_remote_datanode contact_groups admins check_command check_remote_datanode!15!13 }
となり、この場合は稼動しているDataNodeの台数が15台以下になると「WARNING」アラートが、
13台以下になると、「CRITICAL」アラートが出る。
インフラエンジニアのためのHadoop情報 障害復旧のために [Hadoop]
これまでの障害復旧の話で分かるように、Hadoopの障害復旧には、NameNodeのメタデータが
きちんとバックアップされて、いつでも復旧のために使えることが大事です。
ここで少しメタデータついて記しておきます。
HadoopのNameNodeメタデータとは、ファイルシステムに関する情報のことで、通常はNameNode
のメモリ上にあり、チェックポイントごとに編集ログと同期されて、専用のファイルに記録
されます。
専用のファイルとは、edits、fsimage、fstimeの3つあり、それぞれ編集ログ、ファイル情報
チェックポイント時刻情報となります。
editsファイルはファイルへの操作が発生するたびログが記録され、どんどん大きくなって
いきます。editsファイルのログをファイル情報であるfsimageに適用するのは、Secondary
NameNodeの仕事です。PrimaryNameNodeがfsimageを更新するのは、再起動のときだけです。
SecondaryNameNodeは(デフォルトで)1時間おきのチェックポイントでPrimaryNameNodeから
edits,fsimageを取得して、edits中の編集ログをfsimageへ適用し、PrimaryNameNodeへ返却
します。その際、適用済みファイルをSecondaryNameNodeの所定のディレクトリにコピーされ
ます。
このコピーされたedits、fsimage、fstimeの3つのファイルを定期的に他のディレクトリなり
他のホストへ退避しておくと良いでしょう。退避するときには以前のファイルを履歴として
保存するようにしておけば、ある程度任意の時点のファイル構造へ戻すことができます。
参考までに、SendondaryNameNodeのチェックポイント適用済みファイルを指定ディレクトリへ
退避するバッチファイルを挙げておきます。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/nmbackup.pl
きちんとバックアップされて、いつでも復旧のために使えることが大事です。
ここで少しメタデータついて記しておきます。
HadoopのNameNodeメタデータとは、ファイルシステムに関する情報のことで、通常はNameNode
のメモリ上にあり、チェックポイントごとに編集ログと同期されて、専用のファイルに記録
されます。
専用のファイルとは、edits、fsimage、fstimeの3つあり、それぞれ編集ログ、ファイル情報
チェックポイント時刻情報となります。
editsファイルはファイルへの操作が発生するたびログが記録され、どんどん大きくなって
いきます。editsファイルのログをファイル情報であるfsimageに適用するのは、Secondary
NameNodeの仕事です。PrimaryNameNodeがfsimageを更新するのは、再起動のときだけです。
SecondaryNameNodeは(デフォルトで)1時間おきのチェックポイントでPrimaryNameNodeから
edits,fsimageを取得して、edits中の編集ログをfsimageへ適用し、PrimaryNameNodeへ返却
します。その際、適用済みファイルをSecondaryNameNodeの所定のディレクトリにコピーされ
ます。
このコピーされたedits、fsimage、fstimeの3つのファイルを定期的に他のディレクトリなり
他のホストへ退避しておくと良いでしょう。退避するときには以前のファイルを履歴として
保存するようにしておけば、ある程度任意の時点のファイル構造へ戻すことができます。
参考までに、SendondaryNameNodeのチェックポイント適用済みファイルを指定ディレクトリへ
退避するバッチファイルを挙げておきます。
http://github.com/so-net-developer/Hadoop/blob/master/scripts/nmbackup.pl
インフラエンジニアのためのHadoop情報 障害復旧その2 [Hadoop]
PrimaryNameNodeの障害が取り除けず、サーバをあきらめてSecondaryNameNodeをPrimary
として入れ替える場合の手順を紹介します。
この場合は、クラスタ中のホストが指し示していたプライマリNameNodeのアドレスを、これまで
SecondaryNameNodeだったアドレスに切り替えます。手順を以下に示します。セカンダリをプラ
イマリに昇格するイメージです。
PrimaryNameNodeは停止しているものとする。(停止していない場合は停止する)
SecondaryNameNodeを停止します。
チェックポイントのメタデータをNameNodeのメタデータとしてコピーする。
NameNodeのアドレスを変更する。(srv2.example.comが新しいPrimaryNameNode)
新プライマリNameNodeとして起動する。
他のデータノードでも、新プライマリNameNodeのアドレスを参照するように変更する。
全てのデータノードで以下の設定を変更します。
DataNodeの起動直後に、fsckコマンドを実行すると「Under replicate」のエラーが出
ます。しばらくすると再配置が行われ、エラーは解消します。
として入れ替える場合の手順を紹介します。
この場合は、クラスタ中のホストが指し示していたプライマリNameNodeのアドレスを、これまで
SecondaryNameNodeだったアドレスに切り替えます。手順を以下に示します。セカンダリをプラ
イマリに昇格するイメージです。
PrimaryNameNodeは停止しているものとする。(停止していない場合は停止する)
$ sudo /sbin/service hadoop-0.20-namenode stop
SecondaryNameNodeを停止します。
$ sudo /sbin/serivce hadoop-0.20-secondarynamenode stop
チェックポイントのメタデータをNameNodeのメタデータとしてコピーする。
$ cd /var/lib/hadoop-0.20/cache/hadoop/dfs/name/current $ sudo cp ../../namesecondary/previous.checkpoint/* .
NameNodeのアドレスを変更する。(srv2.example.comが新しいPrimaryNameNode)
$ sudo vi /etc/hadoop-0.20/conf/core-site.xml↓ fs.default.name hdfs://srv1.example.com:8020 fs.default.name hdfs://srv2.example.com:8020
新プライマリNameNodeとして起動する。
$ sudo /sbin/service hadoop-0.20-namenode start
他のデータノードでも、新プライマリNameNodeのアドレスを参照するように変更する。
全てのデータノードで以下の設定を変更します。
$ sudo vi /etc/hadoop-0.20/conf/core-site.xml↓ fs.default.name hdfs://srv1.example.com:8020 $ sudo /sbin/service hadoop-0.20-datanode restart fs.default.name hdfs://srv2.example.com:8020
DataNodeの起動直後に、fsckコマンドを実行すると「Under replicate」のエラーが出
ます。しばらくすると再配置が行われ、エラーは解消します。