MapReduce實例——WordCount

第一步:創建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的執行進度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章