EclipseにHadoopの開発環境を作る。
2014/6/13
新しい記事があります。
「EclipseでHadoop2.4の開発環境を作る&ワードカウントのプログラムを作成する。」
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Hadoopを実験するにあたって、プログラムが作れる環境を構築した。
構築には、「30 分で NetBeans を使って Hadoop のプログラムを作ってみる」 を参考にさせていただいた。ただし、慣れているEclipse(Juno)を使うことにした。
まず、Eclipseの本家ページより、Eclipse Juno JEEをダウンロードして、抵当な場所に解凍し、wordbenchを開くところまでやる。
次にhadoopの本家サイトより、hadoop-1.1.2をダウンロードし、ホームディレクトリに解凍、以下のようなシンボリックリンクを張った。
Javaプロジェクトの作成
javaパースペクティブでJavaプロジェクトを作成する。ここでは、プロジェクト名をhadoopsampleとした。
デフォルトパッケージにMain.javaを作成する
Main.javaは、参考サイトのサンプル(Hadoopのサイトのサンプルと思われる)を移植する。
このMain.javaは、入力ファイルの存在するディレクトリ(Users/tetsuya/input)と、出力を行うディレクトリ(Users/tetsuya/output)を引数に指定して、inputディレクトリにあるファイルをさらって語句のカウントを行い、結果をoutputディレクトリに書き出すもので、これらは実行時の引数として渡す。
import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; 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.Reducer; import org.apache.hadoop.mapreduce.Mapper; 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; /** * * Mainクラス * * 引数で指定した入力ファイルからWord Countを行う。 * */ public class Main { 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 tk = new StringTokenizer(line); while(tk.hasMoreTokens()){ word.set(tk.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)); } } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { Job job = new Job(new Configuration(), "wordcount"); job.setJarByClass(Main.class); 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); System.out.println(success); } }
プロジェクト名を右クリックし、プロパティーを選択、Java Build Pathの「Add External JARs」で、/Users/tetsuya/hadoop直下、Users/tetsuya/hadoop/lib下に存在するjarファイルを追加する。
Main.java実行時にhadoopの実行環境を教えなければならない(ただし、Hadoopとしての分散環境を構築しているわけではないので、Javaアプリとして実行されるだけ)ので、Main.javaの引数とVMオプションを設定する。
Main.javaを選択し、右クリック、プロパティーで、run/ debug Settingsを選ぶ。newをおして、Argumentタブを選択し、以下を設定する。
引数(Argument):/Users/tetsuya/input /Users/tetsuya/output
VMオプション(VM Argument):-Xmx1000m -Dhadoop.log.dir=/Users/tetsuya/hadoop/logs -Dhadoop.log.file=hadoop.log -DHadoop.home.dir=/Users/tetsuya/hadoop -Dhadoop.id.str=host -Dhadoop.root.logger=INFO,console -Dhadoop.policy.file=hadoop-policy.xml
Javaプログラムの実行
User/tetsuya/inputにデータを作成する。
echo aaa bbb ccc bbb > ./input/input.txt
outputフォルダーを作成しておくとエラーが出てしまうので作成しない。
以下がコンソールログ
2013-06-15 10:59:36.264 java[58712:1203] Unable to load realm info from SCDynamicStore 13/06/15 10:59:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 13/06/15 10:59:36 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same. 13/06/15 10:59:36 WARN mapred.JobClient: No job jar file set. User classes may not be found. See JobConf(Class) or JobConf#setJar(String). 13/06/15 10:59:36 INFO input.FileInputFormat: Total input paths to process : 1 13/06/15 10:59:36 WARN snappy.LoadSnappy: Snappy native library not loaded 13/06/15 10:59:37 INFO mapred.JobClient: Running job: job_local_0001 13/06/15 10:59:37 INFO mapred.Task: Using ResourceCalculatorPlugin : null 13/06/15 10:59:37 INFO mapred.MapTask: io.sort.mb = 100 13/06/15 10:59:37 INFO mapred.MapTask: data buffer = 79691776/99614720 13/06/15 10:59:37 INFO mapred.MapTask: record buffer = 262144/327680 13/06/15 10:59:37 INFO mapred.MapTask: Starting flush of map output 13/06/15 10:59:37 INFO mapred.MapTask: Finished spill 0 13/06/15 10:59:37 INFO mapred.Task: Task:attempt_local_0001_m_000000_0 is done. And is in the process of commiting 13/06/15 10:59:37 INFO mapred.LocalJobRunner: 13/06/15 10:59:37 INFO mapred.Task: Task 'attempt_local_0001_m_000000_0' done. 13/06/15 10:59:37 INFO mapred.Task: Using ResourceCalculatorPlugin : null 13/06/15 10:59:37 INFO mapred.LocalJobRunner: 13/06/15 10:59:37 INFO mapred.Merger: Merging 1 sorted segments 13/06/15 10:59:37 INFO mapred.Merger: Down to the last merge-pass, with 1 segments left of total size: 32 bytes 13/06/15 10:59:37 INFO mapred.LocalJobRunner: 13/06/15 10:59:37 INFO mapred.Task: Task:attempt_local_0001_r_000000_0 is done. And is in the process of commiting 13/06/15 10:59:37 INFO mapred.LocalJobRunner: 13/06/15 10:59:37 INFO mapred.Task: Task attempt_local_0001_r_000000_0 is allowed to commit now 13/06/15 10:59:37 INFO output.FileOutputCommitter: Saved output of task 'attempt_local_0001_r_000000_0' to /Users/tetsuya/output 13/06/15 10:59:37 INFO mapred.LocalJobRunner: reduce > reduce 13/06/15 10:59:37 INFO mapred.Task: Task 'attempt_local_0001_r_000000_0' done. 13/06/15 10:59:38 INFO mapred.JobClient: map 100% reduce 100% 13/06/15 10:59:38 INFO mapred.JobClient: Job complete: job_local_0001 13/06/15 10:59:38 INFO mapred.JobClient: Counters: 17 13/06/15 10:59:38 INFO mapred.JobClient: File Output Format Counters 13/06/15 10:59:38 INFO mapred.JobClient: Bytes Written=30 13/06/15 10:59:38 INFO mapred.JobClient: FileSystemCounters 13/06/15 10:59:38 INFO mapred.JobClient: FILE_BYTES_READ=376 13/06/15 10:59:38 INFO mapred.JobClient: FILE_BYTES_WRITTEN=97564 13/06/15 10:59:38 INFO mapred.JobClient: File Input Format Counters 13/06/15 10:59:38 INFO mapred.JobClient: Bytes Read=16 13/06/15 10:59:38 INFO mapred.JobClient: Map-Reduce Framework 13/06/15 10:59:38 INFO mapred.JobClient: Map output materialized bytes=36 13/06/15 10:59:38 INFO mapred.JobClient: Map input records=1 13/06/15 10:59:38 INFO mapred.JobClient: Reduce shuffle bytes=0 13/06/15 10:59:38 INFO mapred.JobClient: Spilled Records=6 13/06/15 10:59:38 INFO mapred.JobClient: Map output bytes=32 13/06/15 10:59:38 INFO mapred.JobClient: Total committed heap usage (bytes)=369238016 13/06/15 10:59:38 INFO mapred.JobClient: SPLIT_RAW_BYTES=100 13/06/15 10:59:38 INFO mapred.JobClient: Combine input records=4 13/06/15 10:59:38 INFO mapred.JobClient: Reduce input records=3 13/06/15 10:59:38 INFO mapred.JobClient: Reduce input groups=3 13/06/15 10:59:38 INFO mapred.JobClient: Combine output records=3 13/06/15 10:59:38 INFO mapred.JobClient: Reduce output records=3 13/06/15 10:59:38 INFO mapred.JobClient: Map output records=4 true
outputフォルダーを見ると_SUCCESS、part-r-00000ファイルができており、part-r-00000に実行結果が入っている。
aaa 1 bbb 2 ccc 1