Hadoop0.21のインストールおよび環境設定・動作確認。
HadoopはUNIXを想定しているようなので、Windowsで試す為にはCygwinが必要。
sshが必要なので、CygwinのOpenSSHもダウンロードして設定しておく。
(単独環境で動作させるだけならsshは不要)
HadoopはJavaで動くので、JDK1.6もインストールしておく。
インストールが正常に出来た事を確認するために、コマンドを実行してみる。
作業内容 | 設定内容・実施コマンド | 備考 | |
---|---|---|---|
1 | 環境変数を設定する。 |
$ export HADOOP_HOME=/usr/local/hadoop-0.21.0-c1 |
Cygwin(bash)から実行。 |
2 | HADOOP_HOME/conf/hadoop-env.sh を編集する。 |
export JAVA_HOME=$(cygpath -u $(cygpath -d 'C:\Program Files\Java\jdk1.6.0_20')) |
環境変数JAVA_HOMEの設定。 |
export HADOOP_IDENT_STRING=$HOSTNAME |
HBaseの設定の真似 | ||
3 | HADOOP_HOME/bin/hadoop-config.sh を編集する。 (クラスパスの指定を追加) |
JAVA_PLATFORM=`CLASSPATH=${CLASSPATH} ${JAVA} 〜 ↓ JAVA_PLATFORM=`CLASSPATH=${CLASSPATH} ${JAVA} -cp "$(cygpath -wp $CLASSPATH)" 〜 |
Cygwinに対応していないようなので、クラスパスを変換する。 |
4 | hadoopコマンドを実行してみる。 Usageが表示されればOK! |
$ cd $HADOOP_HOME $ bin/hadoop |
Cygwin(bash)から実行。 |
Windows上の単独環境(スタンドアローン・非分散環境)でサンプルプログラムを実行してみる。
単独環境は通常のマシンのファイルシステムをそのまま使うので、HDFS(Hadoop Distributed File System:Hadoop分散ファイルシステム)は使わない。
設定ファイル(HADOOP_HOME/confの下のxmlファイル)はデフォルトで単独環境用なので、特にいじる必要は無い
。
作業内容 | 設定内容・実施コマンド | 備考 | |
---|---|---|---|
1 | 入力ディレクトリーを作成する。 |
mkdir -p /home/hadoop/example/input |
|
2 | サンプルで入力とするファイルを用意する。 |
cd /home/hadoop/example cp -p $HADOOP_HOME/conf/*.xml input/ |
テキストファイルであれば何でもよい。 |
3 | サンプルを実行してみる。 |
$HADOOP_HOME/bin/hadoop jar \ $(cygpath -w $HADOOP_HOME/hadoop-*-examples*.jar) \ grep input output 'dfs[a-z.]+' |
ずらずらとINFOログがいっぱい出る。 再実行する際はoutput/を削除しておくこと。 「 rm -r output/ 」 |
4 | outputディレクトリーが作られ、 その中に結果ファイルが作られる。 |
ls -l output/ total 1 cat output/*
|
「dfs」で始まる単語の個数が表示されるらしい。 処理が正常終了すると「_SUCCESS」という空ファイルが作られるようだ。 (Hadoop0.21からの新機能と思われる) |
Hadoop(MapReduce)プログラムのコンパイルに必要なライブラリー(jarファイル)は以下の通り。
jarファイル | ソースの場所(Eclipseで添付可能) | 備考 | |
---|---|---|---|
Hadoop | hadoop-common-0.21.0.jar | C:/cygwin/usr/local/hadoop-0.21.0-c1/common/src/java | 以前はhadoop-0.20.2-core.jarだった。 |
hadoop-hdfs-0.21.0.jar | C:/cygwin/usr/local/hadoop-0.21.0-c1/hadoop-hdfs-0.21.0-sources.jar | ||
hadoop-mapred-0.21.0.jar | C:/cygwin/usr/local/hadoop-0.21.0-c1/hadoop-mapred-0.21.0-sources.jar |
package jp.hishidama.hadoop.wordcount;
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.Cluster; 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 ret = ToolRunner.run(new WordCount(), args); System.exit(ret); }
@Override
public int run(String[] args) throws Exception {
Cluster cluster = new Cluster(getConf());
Job job = Job.getInstance(cluster, getConf());
job.setJobName("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;
}
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> { private IntWritable result = new 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(); } result.set(sum); context.write(key, result); } } }
Jobインスタンスの生成で、new Job()が非推奨になった。
Job.
getInstance()を使って生成するようだ。
その為には0.21で新しく導入されたClusterというクラスを指定する必要がある。
あと、Eclipse3.6で
試しているんだけど、ToolやToolRunnerクラスが(非推奨扱いで)警告になる…。
どこにも@Deprecatedは無いのに、不思議だ…。
Hadoop0.20.2と0.21.0の差を分かる範囲で。
変更対象 | 変更内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
bin | hadoop | 処理内容の一部が別のシェルに分割された。 HDFS操作関連はhdfsシェル、MapReduce実行関連はmapredシェルを使う。 |
|||||||||||||||
hdfs | 新設。HDFS操作を行うシェル。 namenodeのフォーマットやfsck(ファイルシステムチェック)等。 namenodeやdatanodeの起動オプションもあるが、これはstart-dfs.shから使われる。 |
||||||||||||||||
mapred | 新設。MapReduce関連プロセスの起動を行うシェル。 jobtrackerやtasktrackerの起動はstart-mapred.shから呼ばれる。 |
||||||||||||||||
start-all.sh stop-all.sh |
非推奨になった。Hadoopの起動はstart-dfs.shとstart-mapred.shを実行する。 | ||||||||||||||||
conf | fair-scheduler.xml mapred-queues.xml |
新規追加。 | |||||||||||||||
common hdfs mapred |
今まで、binやivy・src等は一箇所にまとまっていたが、それらも分割された。
|
変更対象 | 変更内容 | ||
---|---|---|---|
分類 | パッケージ | クラス名 | |
common | fs | FileContext | 新設。 以前のFileSystemの代わりに使用する。 |
fs | FileStatus | シンボリックリンクが扱えるようになった模様。 また、isDir()が非推奨。isDirectory()を使う。 |
|
mapred | mapreduce | Cluster | 新設。 |
mapreduce | Job | コンストラクターが非推奨になった。 Job.getInstance()を使用する模様。 この引数にはClusterインスタンスを渡す必要がある。 |
RegexMapper.GROUP = "mapreduce.mapper.regexmapper..group
";
←ピリオド2つって本当?