MapReduce流程
start-dfs.sh //开启hdfs start-yarn.sh //开启yarn
2.yarn组件依赖于hdfs组件。所以使用MapReduce必须引入common包、hdfs包、yarn包和MapReduce包。jar包位置位于hadoop/share/hadoop里。将common、hdfs、yarn、MapReduce文件夹下的所有jar包及其依赖包导入到项目中。若使用maven开发在pom.xml中引入hadoop的依赖即可。
3.素材获取。这里使用苏轼的水调歌头-明月几时有
明月几时有,把酒问青天。
不知天上宫阙,今夕是何年?
我欲乘风归去,又恐琼楼玉宇,
高处不胜寒。
起舞弄清影,何似在人间!
转朱阁,低绮户,照无眠。
不应有恨,何事长向别时圆?
人有悲欢离合,月有阴晴圆缺,
此事古难全。
但愿人长久,千里共婵娟。
4.MapReduce是有自己的一套编程模型
6.开发我们的Reduce类 Reduce类 规范 必须得 继承Reducer类 并且重写Reducer方法 把我们Map类输出的结果 作为输入 使用之后会把这个临时文件给删除掉
7.开发Driver类 Driver类用来关联HDFS Mapper Reducer3个类
/** * mapper阶段按行读取数据 * LongWritable 为全文的总字数 * Text 输入数据格式 * Text 输出的key数据格式 * IntWritable 输出的value数据格式 */ public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { public void map(LongWritable ikey, Text ivalue, Context context) throws IOException, InterruptedException { char[] charArray = ivalue.toString().replace(",", "").replace("。", "").replace("?", "").toCharArray(); for (char c : charArray) { context.write(new Text(String.valueOf(c)), new IntWritable(1));//写入到临时文件当中 } } }
map阶段过后,数据将变成如下情况:
人有悲欢离合 月有阴晴圆缺
人 1 有 1 悲 1 欢 1 离 1 合 1 月 1 有 1 阴 1 晴 1 圆 1 缺 1
临时文件将会把相同的key聚合起来变成如下情况:
人 [1] 有 [1,1] 悲 [1] 欢 [1] 离 [1] 合 [1] 月 [1] 阴 [1] 晴 [1] 圆 [1] 缺 [1]
/** * Text 输入到reduce阶段的key的数据格式 * IntWritable 输入到reduce阶段的value的数据格式 * Text 输出的key的数据格式 * IntWritable 输出的value的数据格式 */ public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text _key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { Iterator<IntWritable> iterator = values.iterator(); int sum = 0; while (iterator.hasNext()) { IntWritable intWritable = (IntWritable) iterator.next(); sum += intWritable.get(); } context.write(_key, new IntWritable(sum)); //输出到最终文件 } }
public class WordCountJob { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://hdp01:9000"); //指定使用的hdfs文件系统 Job job = Job.getInstance(conf, "WordCount"); //任务名 job.setJarByClass(com.blb.core.WordCountJob.class); //指定job类 // TODO: specify a mapper job.setMapperClass(WordCountMapper.class); //指定mapper类 // TODO: specify a reducer job.setReducerClass(WordCountReducer.class); //指定reduce类 job.setMapOutputKeyClass(Text.class); //指定map输出的key数据格式 job.setMapOutputValueClass(IntWritable.class); //指定map输出的value数据格式 // TODO: specify output types job.setOutputKeyClass(Text.class); //指定reduce输出的key数据格式 job.setOutputValueClass(IntWritable.class); //指定reduce输出的value数据格式 // TODO: specify input and output DIRECTORIES (not files) FileInputFormat.setInputPaths(job, new Path("/1.txt")); //指定需要计算的文件或文件夹 FileOutputFormat.setOutputPath(job, new Path("/out")); //指定输出文件保存位置,此文件夹不得存在 if (!job.waitForCompletion(true)) return; } }
三、操作流程
1.写好程序
2.打成jar包
3.上传素材到hdfs
4.上传jar包到linux
hadoop jar wordcount.jar com.blb.core.WordCountJob

hadoop fs -cat /out/part-r-00000

一、准备工作
1.在Windows上准备好hadoop
下载好eclipse插件和hadoop使用Windows编译过bin目录文件,解压至bin目录。下载地址:链接:https://pan.baidu.com/s/1iXp3MeiE8pXS3QevDJ24kw 提取码:mzye
将hadoop插件放入eclipse/plugin里


3.启动eclipse
切换到切换到MapReduce视图
4.打开视图
然后打开Window->show veiw ->mapreduce tools ->mapreduce location

5.在eclipse中设置hadoop路径
Window->首选项->hadoop

6.在eclipse中连接hdfs文件系统
右击MapReduce location

输入ip、端口、登陆名等信息
完成后项目里会有显示 连接成功开始编写代码

二、代购商品统计练习
1.伪造数据
新建项目

下一步
输入项目名即可创建一个MapReduce项目,无需手动导入jar包。
/** *伪造数据 伪造300户的购物需求 */ package com.blb.core; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 300户 每户都会有一个清单文件 * 商品是随机 数量也是随机 * 洗漱用品 脸盆、杯子、牙刷和牙膏、毛巾、肥皂(洗衣服的)以及皂盒、洗发水和护发素、沐浴液 [1-5之间] * 床上用品 比如枕头、枕套、枕巾、被子、被套、棉被、毯子、床垫、凉席 [0 1之间] * 家用电器 比如电磁炉、电饭煲、吹风机、电水壶、豆浆机、台灯等 [1-3之间] * 厨房用品 比如锅、碗、瓢、盆、灶 [1-2 之间] * 柴、米、油、盐、酱、醋 [1-6之间] * 要生成300个文件 命名规则 1-300来表示 * @author Administrator * */ public class BuildBill { private static Random random=new Random(); //要还是不要 private static List<String> washList=new ArrayList<>(); private static List<String> bedList=new ArrayList<>(); private static List<String> homeList=new ArrayList<>(); private static List<String> kitchenList=new ArrayList<>(); private static List<String> useList=new ArrayList<>(); static{ washList.add("脸盆"); washList.add("杯子"); washList.add("牙刷"); washList.add("牙膏"); washList.add("毛巾"); washList.add("肥皂"); washList.add("皂盒"); washList.add("洗发水"); washList.add("护发素"); washList.add("沐浴液"); /////////////////////////////// bedList.add("枕头"); bedList.add("枕套"); bedList.add("枕巾"); bedList.add("被子"); bedList.add("被套"); bedList.add("棉被"); bedList.add("毯子"); bedList.add("床垫"); bedList.add("凉席"); ////////////////////////////// homeList.add("电磁炉"); homeList.add("电饭煲"); homeList.add("吹风机"); homeList.add("电水壶"); homeList.add("豆浆机"); homeList.add("电磁炉"); homeList.add("台灯"); ////////////////////////// kitchenList.add("锅"); kitchenList.add("碗"); kitchenList.add("瓢"); kitchenList.add("盆"); kitchenList.add("灶 "); //////////////////////// useList.add("米"); useList.add("油"); useList.add("盐"); useList.add("酱"); useList.add("醋"); } //确定要还是不要 1/2 private static boolean iswant() { int num=random.nextInt(1000); if(num%2==0) { return true; } else { return false; } } /** * 表示我要几个 * @param sum * @return */ private static int wantNum(int sum) { return random.nextInt(sum); } //生成300个清单文件 格式如下 //输出的文件的格式 一定要是UTF-8 //油 2 public static void main(String[] args) { for(int i=1;i<=300;i++) { try { //字节流 FileOutputStream out=new FileOutputStream(new File("E:\\tmp\\"+i+".txt")); //转换流 可以将字节流转换字符流 设定编码格式 //字符流 BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out,"UTF-8")); //随机一下 我要不要 随机一下 要几个 再从我们的清单里面 随机拿出几个来 数量 boolean iswant1=iswant(); if(iswant1) { //我要几个 不能超过该类商品的总数目 int wantNum = wantNum(washList.size()+1); //3 for(int j=0;j<wantNum;j++) { String product=washList.get(random.nextInt(washList.size())); writer.write(product+"\t"+(random.nextInt(5)+1)); writer.newLine(); } } boolean iswant2=iswant(); if(iswant2) { //我要几个 不能超过该类商品的总数目 int wantNum = wantNum(bedList.size()+1); //3 for(int j=0;j<wantNum;j++) { String product=bedList.get(random.nextInt(bedList.size())); writer.write(product+"\t"+(random.nextInt(1)+1)); writer.newLine(); } } boolean iswant3=iswant(); if(iswant3) { //我要几个 不能超过该类商品的总数目 int wantNum = wantNum(homeList.size()+1); //3 for(int j=0;j<wantNum;j++) { String product=homeList.get(random.nextInt(homeList.size())); writer.write(product+"\t"+(random.nextInt(3)+1)); writer.newLine(); } } boolean iswant4=iswant(); if(iswant4) { //我要几个 不能超过该类商品的总数目 int wantNum = wantNum(kitchenList.size()+1); //3 for(int j=0;j<wantNum;j++) { String product=kitchenList.get(random.nextInt(kitchenList.size())); writer.write(product+"\t"+(random.nextInt(2)+1)); writer.newLine(); } } boolean iswant5=iswant(); if(iswant5) { //我要几个 不能超过该类商品的总数目 int wantNum = wantNum(useList.size()+1); //3 for(int j=0;j<wantNum;j++) { String product=useList.get(random.nextInt(useList.size())); writer.write(product+"\t"+(random.nextInt(6)+1)); writer.newLine(); } } writer.flush(); writer.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
素材格式:

2.mapper
选择文件->新建即可选择新建一个mapper

public class ShopCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { public void map(LongWritable ikey, Text ivalue, Context context) throws IOException, InterruptedException { String[] word = ivalue.toString().split("\t"); context.write(new Text(word[0]), new IntWritable(Integer.parseInt(word[1]))); } }
选择文件->新建即可选择新建一个reducer

public class ShopCountReducer extends Reducer<Text, IntWritable, Text,IntWritable> { public void reduce(Text _key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { // process values int sum=0; for (IntWritable val : values) { int i = val.get(); sum+=i; } context.write(_key,new IntWritable(sum)); } }
public class ShopCountJob { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("fs.defaultFS","hdfs://hdp01:9000"); Job job = Job.getInstance(conf, "ShopCountDriver"); job.setJarByClass(ShopCountJob.class); // TODO: specify a mapper job.setMapperClass(ShopCountMapper.class); // TODO: specify a reducer job.setReducerClass(ShopCountReducer.class); // TODO: specify output types job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); // TODO: specify input and output DIRECTORIES (not files) FileInputFormat.setInputPaths(job, new Path("/upload")); FileOutputFormat.setOutputPath(job, new Path("/out2/")); if (!job.waitForCompletion(true)) return; } }
配置log4j.properties
log4j.rootLogger = debug,stdout log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
右击运行 查看out2结果




浙公网安备 33010602011771号