MapReduser wordcount测试

对worldcount程序分析
1:整个wordcount分为3个阶段
   mapper
   reducer
   driver
   
2:每个阶段的作用
   mapper:对数据进行打散<hello,1><mimi,1>
   reducer:对数据进行聚合<hello,1+1+1>
   driver:提交任务
   
3:详解
   mapper阶段:
               将数据转换成String
               对数据进行切分处理
               把每个单词后加1
               输出到reducer阶段
               
   reducer阶段:
              根据key进行聚合
              输出key出现的总次数

   driver阶段:
             创建任务
             关联使用的Mapper/Reducer类
             指定Mapper输出数据的kv类型
             指定reducer输出的数据的kv类型
             指定数据的输入与输出路径
             提交

#############################################

创建wordCountReducer 类:
package com.zhang_bigdata01;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;

/**
 * Reducer阶段接受的是Mapper输出的数据
 * Mapper的输出是Reducer的输入
 *
 * KeyIn:Mapper输出Key的类型
 * ValueIN:Mapper输出Value的类型
 *
 * Reducer端输出的数据类型,<hello,199>
 * KeyOut:Text
 * ValueOut:IntWritable
 *
 */

public class wordCountReducer extends Reducer<Text, IntWritable,Text,IntWritable>{

    //Key ->单词  Value ->次数
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) 
                                       throws IOException, InterruptedException {
        //1:记录出现的次数
        int sum = 0;
        for (IntWritable v:values) {
            sum += v.get();
        }

        //2:累加求和输出
        context.write(key,new IntWritable(sum));
    }
}

------------------------------------

创建wordCountMap 类:

package com.zhang_bigdata01;

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 java.io.IOException;

/**
 * 数据的输入与输出以Key Value进行传输
 * KeyIN:LongWritable(long)数据的起始偏移量
 * ValueIN:具体数据 Text
 *
 * mapper需要把数据传递到reduce阶段<hello,1>
 *     KeyOut: 单词Text
 *     ValueOut: 出现的次数,IntWritable
 */

public class wordCountMap extends Mapper<LongWritable, Text,Text, IntWritable> {
    //d对数据进行切分
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //1:接入数据
        String line = value.toString();
        //2:对数据进行切分,以空格进行切分
        String[] words = line.split(" ");
        //3:写出以<hello,1>格式
        for (String w:words) {
            //写出reduce端
            context.write(new Text(w),new IntWritable(1));
        }

创建WorldCountCombine类,来优化

package WordCount;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class WorldCountCombine 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));
    }
}

-------------------------------

创建wordCountDriver 类:
package com.zhang_bigdata01;

import org.apache.hadoop.conf.Configuration;
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;
import java.io.IOException;

public class wordCountDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        
        //设置起始时间
        long starttime = System.currentTimeMillis();

        //这里是放在本地测试输入输出路径,注意输出目录需要不存在,也可打包上传hadoop后测试
        args = new String[]{"E:\\bigdata_code\\wcword.txt","E:\\bigdata_code\\out"};
        //1:创建job任务
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);

        //2:指定jar包位置
        job.setJarByClass(wordCountDriver.class);

        //3:关联使用Mapper类,设置Mapper阶段数据输出类型
        job.setMapperClass(wordCountMap.class);

        //4:关联使用Reducer类
        job.setReducerClass(wordCountReducer.class);

        //5:设置Mapper阶段输出的数据类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        //6:设置Reducer阶段输出的数据类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        
         //设置预合并combine
         job.setCombinerClass(WorldCountCombine.class);
        //7:设置数据输入的路径
        FileInputFormat.setInputPaths(job,new Path(args[0]));

        //8:设置数据输出的路径
        FileOutputFormat.setOutputPath(job,new Path(args[1]));

        //9:提交任务
        boolean rs = job.waitForCompletion(true);
        System.exit(rs?0:1);
        
        //设置结束时间,统计程序的执行时间
        long endtime = System.currentTimeMillis();
        System.out.println((endtime - starttime)/1000);
    }
}

这里统计的是/var/log/messages,统计结果如下:

    5568
"centos"    22
"d:group:adm:r-x,d:group:wheel:r-x":    22
"group:adm:r-x,group:wheel:r-x":    22
"pci=nocrs"    11
"plymouth    1
#011Offload    22
#011RCU    11
#011chunk_size:    11
#011lose    11
#011num_reg:    11

---------------------------------------------------

也可以在hadoop服务器上统计,结果相同
hadoop jar zhang-1.0-SNAPSHOT.jar  com.zhang_bigdata01.WordCountMain /opt/hadoop_data/messages /opt/hadoop_data/out1   

---------------------------------------------------

在IDEA中测试是报错如下:

Exception in thread"main"java.lang.UnsatisfiedLinkError:org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z

原因是:C:\Windows\System32下缺少hadoop.dll

解决方法:

将hadoop的bin下的hadoop.dll再往C:\Windows\System32下拷贝一份重启eclipse或者idea即可解决。

如果经历以上步骤之后还是第三个错误。

分析错误:错误指向的是hadoop的源码NativeIO.java的606行代码。

 

Windows的唯一方法用于检查当前进程的请求,在给定路径的访问权限,所以我们可以给予能访问的权限,可以在当前工程中临时先修改源代码,return true 时允许访问。

解决错误:

1.鼠标点击错误中的(NativeIO.java:606)会跳转到源码类中。

2.查看NativeIO.java的包package路径,在当前工程建立相同的package。

3.将源码NativeIO.java拷贝到步骤2建立的工程中。

4.找到错误提示的代码处,606行进行如下修改,即可解决。

//return access0(path, desiredAccess.accessRight());
return true;

         
               

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值