S-JIS[2012-06-08] 変更履歴

Hadoop CDH4

CDH4(Cloudera's Distribution including Apache Hadoop v4)のインストールについて。


CDH4の概要

CDH(Cloudera's Distribution including Apache Hadoop)は、Hadoopのディストリビューション。
CDH4はHadoop2.0(旧Hadoop0.23)がベースとなっている。

CDH4のHadoopはMapReduce v1(MRv1)とYARN(MRv2)の二種類ある。
MRv1は従来と同じくJobTrackerやTaskTrackerを使用して動作する。
YARNは新しい方式で、ResourceManager・NodeManager(やApplicationMaster/Container)を使用して動作する。
(Hadoop0.23ではインストールは一種類で、パラメーターmapreduce.framework.nameによってどちらで動かすか変化させていたが、CDH4ではインストール自体を分けた模様)

MRv1でもYARNでもHDFS(NameNodeやDataNode)を使うのは同じ。
また、クライアント用ライブラリーも共通。

自分がどちらの環境で動かしたいかによって、MRv1とYARNのどちらかをインストールする。


CentOSへのインストール

CentOSへは、yumコマンドを使用してインストールすることが出来る。

  1. JDK1.6をインストールしておく。
  2. yumリポジトリーにClouderaのサイトを追加する。
    どのOSの場合にどのrepoファイルをダウンロードすればよいかは、CDH Version and Packaging Informationに載っている。
    CentOS5 http://archive.cloudera.com/cdh4/redhat/5/x86_64/cdh/cloudera-cdh4.repo
    CentOS6(32bit) http://archive.cloudera.com/cdh4/redhat/6/i386/cdh/cloudera-cdh4.repo
    CentOS6(64bit) http://archive.cloudera.com/cdh4/redhat/6/x86_64/cdh/cloudera-cdh4.repo
    # cd /etc/yum.repos.d/
    # wget http://archive.cloudera.com/cdh4/redhat/5/x86_64/cdh/cloudera-cdh4.repo
    # yum update yum
    # yum search hadoop

MRv1のインストール

MRv1のCDH4を使うには、以下のものをインストールする。
(開発環境(単独環境(スタンドアローン環境))を作る場合は、全部同じマシンにインストールすればよい。ただしSecondaryNameNodeは不要)

コンポーネント コマンド 備考
JobTracker
yum install hadoop-0.20-mapreduce-jobtracker
JobTrakcerを稼動させるマシンにインストールする。
NameNode
yum install hadoop-hdfs-namenode
NameNodeを稼動させるマシンにインストールする。
Secondary NameNode
yum install hadoop-hdfs-secondarynamenode
Secondary NameNodeを稼動させるマシンにインストールする。
TaskTracker
DataNode
yum install hadoop-0.20-mapreduce-tasktracker hadoop-hdfs-datanode
各スレーブノードにインストールする。
Client
yum install hadoop-client
Hadoopのクライアントマシンにインストールする。

YARNのインストール

YARNのCDH4を使うには、以下のものをインストールする。
(開発環境(単独環境(スタンドアローン環境))を作る場合は、全部同じマシンにインストールすればよい。ただしSecondaryNameNodeは不要)

コンポーネント コマンド 備考
Resource Manager
yum install hadoop-yarn-resourcemanager
Resource Manager(従来のJobTracker相当)を稼動させるマシンにインストールする。
NameNode
yum install hadoop-hdfs-namenode
NameNodeを稼動させるマシンにインストールする。
Secondary NameNode
yum install hadoop-hdfs-secondarynamenode
Secondary NameNodeを稼動させるマシンにインストールする。
NodeManager
DataNode
yum install hadoop-yarn-nodemanager hadoop-hdfs-datanode hadoop-mapreduce
各スレーブノードにインストールする。
(従来のTaskTracker相当)
HistoryServer
YarnProxyServer
yum install hadoop-mapreduce-historyserver hadoop-yarn-proxyserver
どこかのサーバー(1台のみ)にインストールする。
Client
yum install hadoop-client
Hadoopのクライアントマシンにインストールする。

環境設定

従来のHadoopでは環境変数HADOOP_HOMEでHadoopをインストールしている場所を示していた。
CDH4では、HADOOP_HOMEは使われなくなり、もっと色々な環境変数に分離している。

環境変数 デフォルト値(指している場所) 備考
HADOOP_CONF_DIR /etc/hadoop/conf 設定ファイル
HADOOP_COMMON_HOME /usr/lib/hadoop Hadoop共通
HADOOP_HDFS_HOME /usr/lib/hadoop-hdfs HDFS関連
HADOOP_MAPRED_HOME /usr/lib/hadoop-mapreduce MapReduce関連
YARN_HOME /usr/lib/hadoop-yarn  
JSVC_HOME /usr/libexec/bigtop-utils  

これらの環境変数は/etc/default/hadoopというファイル(シェルスクリプト)で設定できるようになっているので、.bash_profile辺りで実行するようにしておけばよい。

$HOME/.bash_profileや/etc/bashrc等への追加:

. /etc/default/hadoop

$HADOOP_CONF_DIRの指す場所(/etc/hadoop/conf)はCDH3の時と同様にシンボリックリンクとなっており、alternativesコマンドで切り替えられる。

# alternatives --display hadoop-conf
hadoop-conf -ステータスは自動です。
リンクは現在 /etc/hadoop/conf.empty を指しています。
/etc/hadoop/conf.empty - 優先項目 10
現在の「最適」バージョンは /etc/hadoop/conf.empty です。

また、hdfs・mapred・yarnというUNIXユーザーが作られる。


動作確認

CDH4でも従来と同じサンプルが用意されているので、動作確認に使える。

$ hadoop version
Hadoop 2.0.0-cdh4.0.0
$ cd /tmp
$ hadoop jar $HADOOP_MAPRED_HOME/hadoop-mapreduce-examples.jar pi 4 1000

hadoopコマンドは/usr/binの下に作られているので、絶対パスを指定しなくても実行できる。


ソースのダウンロード

CDH4ではyumでソースがダウンロードできないようなので、別途アーカイブをダウンロードしてくる。

  1. Clouderaのトップページの上部のメニューバーっぽいところからDownloadsをクリックし、Downloadsページを開く。
  2. CDH4の「Downloads and Documentation」をクリックし、CDH Downloadsページを開く。
  3. Tarballの「Download」をクリックし、CDH4 Downloadable Tarballsページを開く。
  4. 色々なコンポーネントの一覧があるので、hadoop-2.0.0のDownload列のアイコンをクリックするとアーカイブ(hadoop-2.0.0-cdh4.0.0.tar.gz)がダウンロードされる。
  5. 適当な場所に解凍すると、hadoop-2.0.0-cdh4.0.0/srcにソースがある。(Eclipseのソースの添付ではこのディレクトリーを指定すればよい)

HBaseHivePigSqoop等もダウンロードできるようだ。


WordCountサンプル

MapReduceプログラム自体は従来のものとほぼ変わらない。
従来(Hadoop0.21の新API)のWordCountとの違いは、Jobのインスタンス生成の方法がgetInstance()を使うようになっただけ。

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class WordCount extends Configured implements Tool {
	public static void main(String[] args) throws Exception {
		int r = ToolRunner.run(new WordCount(), args);
		System.exit(r);
	}
	public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
		private final static IntWritable one = new IntWritable(1);
		private Text word = new Text();

		@Override
		protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
			String line = value.toString();
			StringTokenizer tokenizer = new StringTokenizer(line);
			while (tokenizer.hasMoreTokens()) {
				word.set(tokenizer.nextToken());
				context.write(word, one);
			}
		}
	}
	public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {

		@Override
		protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
			int sum = 0;
			for (IntWritable value : values) {
				sum += value.get();
			}
			context.write(key, new IntWritable(sum));
		}
	}
	@Override
	public int run(String[] args) throws Exception {
		Job job = Job.getInstance(getConf(), "wordcount");
		job.setJarByClass(getClass());

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);

		job.setMapperClass(Map.class);
		job.setCombinerClass(Reduce.class);
		job.setReducerClass(Reduce.class);

		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);

		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));

		boolean success = job.waitForCompletion(true);
		return success ? 0 : 1;
	}
}

コンパイルする為には以下のjarファイルをCLASSPATH(Eclipseのビルドパス)に加える。

jarファイル 備考
$HADOOP_COMMON_HOME/hadoop-common.jar hadoop.confやhadoop.io・hadoop.util等の共通クラス
$HADOOP_MAPRED_HOME/hadoop-mapreduce-client-core.jar hadoop.mapreduce系(Job・Mapper・ReducerやInputFormat・OutputFormat)クラス

擬似分散環境(CentOS)

CentOSで擬似分散環境を構築してみる。
(擬似分散環境は1台のマシン上で全てのデーモンを動かすモード)

yumコマンドで擬似分散環境の設定ファイルをインストールすることが出来る。(repoファイルや単独環境モジュールはインストール済みである前提)
ただしMRv1とYARNではインストールするアーカイブが異なる。
両方を同時にインストールする(共存させる)ことは出来ないので注意。

参考: Installing CDH4 on a Single Linux Node in Pseudo-distributed Mode


MRv1の擬似分散モード

  1. 擬似分散モードの設定をインストールする。
    # yum install hadoop-0.20-conf-pseudo
    # alternatives --display hadoop-conf
    hadoop-conf -ステータスは自動です。
    リンクは現在 /etc/hadoop/conf.pseudo.mr1 を指しています。
    /etc/hadoop/conf.empty - 優先項目 10
    /etc/hadoop/conf.pseudo.mr1 - 優先項目 30
    現在の「最適」バージョンは /etc/hadoop/conf.pseudo.mr1 です。
  2. HDFSをフォーマットする。(hdfsユーザーで実行する)
    # sudo -u hdfs hdfs namenode -format
  3. HDFSデーモンを開始する。
    (NameNode・SecondaryNameNode・DataNode)
    # for service in /etc/init.d/hadoop-hdfs-*
      do
        $service start
      done
  4. /tmpディレクトリーを作成する。(これを作っておかないと、後でトラブルが出る可能性があるらしい)
    # sudo -u hdfs hadoop fs -mkdir /tmp
    # sudo -u hdfs hadoop fs -chmod -R 1777 /tmp
    $ hadoop fs -ls /
  5. MapReduce用のディレクトリーを作成する。
    # su - hdfs
    $ hadoop fs -mkdir /var/lib/hadoop-hdfs/cache/mapred/mapred/staging
    $ hadoop fs -chmod 1777 /var/lib/hadoop-hdfs/cache/mapred/mapred/staging
    $ hadoop fs -chown -R mapred /var/lib/hadoop-hdfs/cache/mapred
    $ exit
    $ hadoop fs -ls -R /
  6. MapReduceデーモンを開始する。
    (JobTracker・TaskTracker)
    # for service in /etc/init.d/hadoop-0.20-mapreduce-*
      do
        $service start
      done
  7. ユーザー用ディレクトリーを作っておく。
    # sudo -u hdfs hadoop fs -mkdir /user/hishidama
    # sudo -u hdfs hadoop fs -chown hishidama /user/hishidama

擬似分散モードが正常に稼動していれば、http://localhost:50030でジョブ一覧、http://localhost:50070でHDFSの状態が見られる。


サンプルを実行してみる。

$ hadoop jar $HADOOP_MAPRED_HOME/hadoop-mapreduce-examples.jar pi 4 1000
$ vi example.txt
$ hadoop fs -put example.txt
$ hadoop jar $HADOOP_MAPRED_HOME/hadoop-mapreduce-examples.jar wordcount example.txt output
$ hadoop fs -cat output/part-r-00000

しかしこれ、自分の環境では、hdfsユーザーだとちゃんと実行できたが、自ユーザーだとエラーになった。

INFO mapreduce.Cluster: Failed to use org.apache.hadoop.mapred.LocalClientProtocolProvider due to error: Invalid "mapreduce.jobtracker.address" configuration value for LocalJobRunner : "localhost:8021"
ERROR security.UserGroupInformation: PriviledgedActionException as:hishidama (auth:SIMPLE) cause:java.io.IOException: Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.
java.io.IOException: Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.
	at org.apache.hadoop.mapreduce.Cluster.initialize(Cluster.java:121)
	〜

色々試したところ、ユーザーとは関係なく、HADOOP_MAPRED_HOMEの設定有無によってエラーになったりならなかったりする事が分かった。
HADOOP_MAPRED_HOMEが空だと(設定されていないと)正常に動作する。不思議不思議。
hdfsユーザーは/etc/default/hadoopを実行するようにしてなかったので、環境変数が設定されていなかったので動いたのだろう。(jarファイルは環境変数を使わずにフルパスで指定していた)

$ export HADOOP_MAPRED_HOME=
$ hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar pi 4 1000

たぶん、HADOOP_MAPRED_HOMEの下にある何らかの設定ファイルの影響を受けてローカルモード(擬似分散モードでない)と判断され、LocalJobRunnerを使おうとしてエラーになったのだろう。

mapreduce.framework.nameがlocalだとLocalJobRunnerが選択されるが、LocalJobRunnerはmapreduce.jobtracker.addressが「local」でないとエラーになる(今回は擬似分散モードなので、「localhost:8021」になっている)。
というチェックをLocalClientProtocolProvider#create()がやっている。

ただ、HADOOP_MAPRED_HOMEの下には設定ファイル(xmlファイル)が見当たらない。不思議不思議。


YARNの擬似分散モード

  1. 擬似分散モードの設定をインストールする。
    # yum install hadoop-conf-pseudo
    # alternatives --display hadoop-conf
    hadoop-conf -ステータスは自動です。
    リンクは現在 /etc/hadoop/conf.pseudo を指しています。
    /etc/hadoop/conf.empty - 優先項目 10
    /etc/hadoop/conf.pseudo - 優先項目 30
    現在の「最適」バージョンは /etc/hadoop/conf.pseudo です。
  2. HDFSをフォーマットする。(hdfsユーザーで実行する)
    # sudo -u hdfs hdfs namenode -format
  3. HDFSデーモンを開始する。
    (NameNode・SecondaryNameNode・DataNode)
    # for service in /etc/init.d/hadoop-hdfs-*
      do
        $service start
      done
  4. /tmpディレクトリーを作成する。(これを作っておかないと、後でトラブルが出る可能性があるらしい)
    # sudo -u hdfs hadoop fs -mkdir /tmp
    # sudo -u hdfs hadoop fs -chmod -R 1777 /tmp
    $ hadoop fs -ls /
  5. YARN用のディレクトリーを作成する。
    # su - hdfs
    $ hadoop fs -mkdir /var/log/hadoop-yarn
    $ hadoop fs -chown yarn:mapred /var/log/hadoop-yarn
    $ hadoop fs -mkdir /tmp/hadoop-yarn/staging
    $ hadoop fs -chmod -R 1777 /tmp/hadoop-yarn/staging
    $ hadoop fs -mkdir /tmp/hadoop-yarn/staging/history/done_intermediate
    $ hadoop fs -chmod -R 1777 /tmp/hadoop-yarn/staging/history/done_intermediate
    $ hadoop fs -chown -R mapred:mapred /tmp/hadoop-yarn/staging
    $ exit
    $ hadoop fs -ls -R /
  6. ユーザー用ディレクトリーを作っておく。
    # sudo -u hdfs hadoop fs -mkdir /user/hishidama
    # sudo -u hdfs hadoop fs -chown hishidama:hishidama /user/hishidama
  7. YARNデーモンを開始する。
    # /etc/init.d/hadoop-yarn-resourcemanager start
    # /etc/init.d/hadoop-yarn-nodemanager start
    # /etc/init.d/hadoop-mapreduce-historyserver start

擬似分散モードが正常に稼動していれば、http://localhost:50070でHDFSの状態、http://localhost:19888でジョブの履歴(JobHistory)が見られる。
JobHistoryは履歴なので、実行中のジョブは一覧に出てこない。


サンプルを実行してみる。

$ hadoop jar $HADOOP_MAPRED_HOME/hadoop-mapreduce-examples.jar pi 4 1000
$ vi example.txt
$ hadoop fs -put example.txt
$ hadoop jar $HADOOP_MAPRED_HOME/hadoop-mapreduce-examples.jar wordcount example.txt output
$ hadoop fs -cat output/part-r-00000

YARNだとMRv1と違って特に問題なく実行できる。


Hadoop目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま