三、MapReduce理解

一、第一个MapReduce应用程序

    1.实现继承Mapper的类:WordCountMapper

 // 实现Map程序
public static class WordCountMapper extends Mapper<LongWritable,Text,Text,LongWritable>{

     public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
         //将传进来的字符串进行分割

         System.out.println("Usage:3.1");
         String strs = value.toString();

         System.out.println("Usage:3.1.1");
         String[] str = strs.split(" ");


         System.out.println("Usage:3.2");
         //将分割的字符串进行赋值
         for(String key2 : str ){
             context.write(new Text(key2),new LongWritable(1));
         }

         System.out.println("Usage:3.3");
     }
 }

    2.实现继承Reducer的类:WordCountReducer

 // 实现Reduce程序
public static class WordCountReduce extends Reducer<Text,LongWritable,Text,LongWritable>{

     public void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
         //定义一个求和值默认为0
         long sum = 0;


         // 将相同key键的值进行累加
         for (LongWritable i : values){
             sum+=i.get();
         }


         context.write(key,new LongWritable(sum));
     }
 }

    3.主程序中创建一个job去执行mapreducer程序

public static void main(String[] args) throws Exception{

    Configuration conf = new Configuration();

    Job job = new Job(conf);
    //设置程序入口
    job.setJarByClass(WordCountDemo.class);

    // 设置文件输入数据
    FileInputFormat.setInputPaths(job,new Path(args[0]));

    //设置文件输出数据
    FileOutputFormat.setOutputPath(job,new Path(args[1]));

    // 设置Map
    job.setMapperClass(WordCountMapper.class);
    job.setMapOutputKeyClass(Text.class);  //注意输出的key value值,否则报异常
    job.setOutputValueClass(LongWritable.class);

    // 设置Reduce
    job.setReducerClass(WordCountReduce.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(LongWritable.class);

    // 启动
    job.waitForCompletion(true);
}

二、Hadoop的序列化

    序列化:是指把结构化的对象转化成字节流

    逆序列化:是序列化的逆序过程,是将字节流转化成结构化对象

    * 编写Hadoop序列化程序

        1.创建一个Emp对象并实现序列化接口Writable

        2.实现Writable的两个方法:write()、readFields()方法

        3.实现Emp属性的getter/setter方法以及toString()

        4.创建一个EmpMain类来实现序列化的MapReduce程序

        5.创建一个Mapper<LongWritable,Text,LongWritable,Emp>类

        

// 分词
String[] vals = value.toString().split(",");

//设置属性
Emp emp = new Emp();
emp.setEmpid(Integer.parseInt(vals[0]));//员工号
emp.setName(vals[1]);
emp.setJob(vals[2]);

try {
    emp.setMgr(Integer.parseInt(vals[3]));
} catch (NumberFormatException e) {
    emp.setMgr(0);
}

emp.setHiredate(vals[4]);
emp.setPrice(Integer.parseInt(vals[5]));
try {
    emp.setJiangjin(Integer.parseInt(vals[6]));
} catch (NumberFormatException e) {
    emp.setJiangjin(0);
}

// 输出
context.write(new LongWritable(emp.getEmpid()),emp);
        6.在main方法中配置信息,导出jar包在hadoop上运行

三、实现MapReduce排序

    注意:实现排序过程中是通过key来进行排序,而在value中是不进行排序

    1.Emp对象实现WritableComparable<Emp>接口的方法:comparaTo(),按规则薪资升序

    2.在实现MapReduce的Mapper过程中,需将Emp调整为key2输出,这样才能排序

    

四、实现MapReduce分区

    MapReduce有一个默认的分区规则:只会产生一个分区

    1.在创建分区程序过程中需要创建继承Partitioner的类并实现getPartition()方法

    2.通过reducer的数目进行分区,编写分区规则

    

    // 建立分区
public static class EmpPartition extends Partitioner<LongWritable,Emp>{

    @Override
    public int getPartition(LongWritable key, Emp emp, int num) { // num为Reducer的数目
        int deptno = emp.getDeptno();
        if (deptno == 10 ){
            return 1 % num;
        }else if (deptno == 20 ){
            return 2 % num;
        }else{
            return 3 % num;
        }
    }
}

    3.在main主函数中添加分区规则

    

//设置分区Partitioner
job.setPartitionerClass(EmpPartition.class);
// 设置reducer数目大小
job.setNumReduceTasks(3);
    4.reducer数目的大小决定需要将数据分成多个区

五、MapReduce的Combiner

    Combiner是一个特殊的Reducer,它会在Mapper端对数据进行一次合并,减少IO访问,输出到Reducer的数据量减少,提高效率。但Combiner在求平均值等一些特殊情况不能使用,所以在使用Combiner过程中需慎重考虑。

    通过在主程序设置 job.setCombinerClass(EmpReduce.class) 即可

六、MapReduce的Shuffle

    参考:https://blog.csdn.net/u012151684/article/details/72589302

    


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值