第一步:創建MapReduce_Test項目 導入hdfs、mapreduce和yarn相關jar包
第二步:編寫WordCountMapper類 代碼如下:
package com.xjtuse;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.util.StringUtils;
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
@Override
// 重寫父類的map方法 循環調用 從split後的數據片段中 每讀取一行 調用一次 以該行所在的下標爲key 該行的內容爲value
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
String [] words = StringUtils.split(value.toString(), ' '); // 將文件的每一行中的單詞 以空格進行分割 保存到數組中
// 循環遍歷數組
for(String w : words)
{
context.write(new Text(w), new IntWritable(1)); // 以單詞爲key 1爲value進行輸出
}
}
}
第三步:編寫WordCountReducer類 代碼如下:
package com.xjtuse;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
@Override
// 循環調用reduce方法 進行洗牌後生成的每一組數據調用一次該方法 這一組數據key相同 value可能有很多
protected void reduce(Text arg0, Iterable<IntWritable> arg1, Context arg2)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
// 定義一個變量存放每一組中單詞出現的總數
int sum = 0;
for(IntWritable i : arg1)
{
sum += i.get();
}
arg2.write(arg0, new IntWritable(sum)); // 以單詞爲key 出現的總次數爲value輸出
}
}
第四步:在hdfs下創建/wordcount/input目錄 並將本地的wc.txt文件上傳到該目錄下
第五步:編寫RunJob類 代碼如下:
package com.xjtuse;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class RunJob {
public static void main(String[] args) {
// TODO Auto-generated method stub
Configuration conf = new Configuration();
try {
FileSystem fs =FileSystem.get(conf);
// 通過靜態方法得到job對象
Job job = Job.getInstance(conf);
// 設置Job的執行類入口文件
job.setJarByClass(RunJob.class);
// 設置Job名稱
job.setJobName("wordcount");
// 設置Mapper
job.setMapperClass(WordCountMapper.class);
// 設置Reducer
job.setReducerClass(WordCountReducer.class);
// 設置輸出的key的類型
job.setMapOutputKeyClass(Text.class);
// 設置輸出的value的類型
job.setMapOutputValueClass(IntWritable.class);
// 設置輸入文件的目錄
FileInputFormat.addInputPath(job, new Path("/wordcount/input/wc.txt"));
Path outputpath = new Path("/wordcount/output"); // 這個目錄必須事先不存在
// 如果輸出目錄存在 則刪掉它
if(fs.exists(outputpath))
{
fs.delete(outputpath, true); // true表示遞歸刪除
}
// 設置輸出文件的目錄
FileOutputFormat.setOutputPath(job, outputpath);
// 執行
boolean b = job.waitForCompletion(true);
if(b)
{
System.out.println("Job任務執行成功!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
第六步:將程序打成jar包
在MapReduce_Test項目上右鍵->export->
第七步:將生成的jar包上傳到master上(此處可以是任意一臺虛擬機 因爲每臺虛擬機上的配置文件上都已經說明了Resource Manager是哪臺機器 因此這個java程序在任意一臺機器上都可以運行)
第八步:運行該程序
hadoop jar wc.jar com.xjtuse.RunJob(此處運行的主類需要帶上其所在的包名)
報錯如下:
原因是我的windows本地jdk版本是1.8
而虛擬機上安裝的jdk版本是1.7
在高版本的jdk下編譯的jar包在低版本的jar包上運行 就會報這個錯誤 應該保證windows和虛擬機兩個的jdk版本一致
可以在本地安裝1.7版本的jdk 再重新打成jar包 上傳到Linux上運行即可成功 可以通過瀏覽器查看task的執行進度