• MapReduce学习笔记(2)


      1、Mapper 

        一个类要作为mapper必须实现Mapper接口,并且继承MapReduceBase类。

        Mapper负责数据处理阶段,形式为Mapper<K1,V1,K2,V2>,Mapper只有一个方法map,用于处理一个单独的key/value对。Hadoop预定义了一些非常有用的Mapper

        

       2、Reducer

        一个类要作为Reducer必须实现Reducer接口,并且继承MapReduceBase类。当reducer接受来自各个mapper的输出时,将按照key值对输入数据进行排序,并按照排序结果输出给不同的reducer。

        同样,Hadoop预定义了一些非常有用的reducer类

        

          

       3、Partitioner:重定向Mapper输出

        在笔记(1)中我提到了,在map和reduce阶段中间还有一个非常重要的阶段:将mapper的结果输出给不同的reducer,这就是partitioner的工作。

        默认的做法是对key进行散列来确定reducer,hadoop通过HashPartitioner类强制执行这个策略。但是有时我们想通过key值中的某个属性进行排序,而不是key的整体,使用HashPartitioner就会出错。所以我们需要自己定制partitionger。如前面提到的Edge类,我们希望通过departure属性排序,而不是key((DepartureNode,arrivalNode))进行排序。

      

    public class EdgePartitioner implements Partitioner<Edge, Writable>
    {
        @Override
        public int getPartition(Edge key, Writable value, int numPartitions)
        {
             return key.getDepartureNode().hashCode() % numPartitions;
        }
        @Override
        public void configure(JobConf conf) { }
    }

        这张图也许能更好的帮助理解partitioner:

        每个图是一个key/value对,形状代表key。内部图案代表value。shuffling过后,相同key的图标放入相同的reducer,不同的键也可以放入同一个reducer。partitioner决定放入的位置。

        

      4、Combiner:本地Reducer

        combiner是在map结束后输出之前进行本地reducer,这样可以减少传输量,提高性能。

      5、使用预定义的mapper和reducer类重写WordCount

        

    public class WordCount2 {
        public static void main(String[] args) {
            JobClient client = new JobClient();
            JobConf conf = new JobConf(WordCount2.class);
            FileInputFormat.addInputPath(conf, new Path(args[0]));
            FileOutputFormat.setOutputPath(conf, new Path(args[1]));
            conf.setOutputKeyClass(Text.class);
            conf.setOutputValueClass(LongWritable.class);
            conf.setMapperClass(TokenCountMapper.class);
            conf.setCombinerClass(LongSumReducer.class);
            conf.setReducerClass(LongSumReducer.class);
            client.setConf(conf);
            try {
                JobClient.runJob(conf);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

        注意:以上代码使用hadoop旧的API写成,有许多在新API中不建议使用的类和接口。

  • 相关阅读:
    阿里巴巴研究员叔同:云原生是企业数字创新的最短路径
    【OpenYurt 深度解析】边缘网关缓存能力的优雅实现
    K8s 原生 Serverless 实践:ASK 与 Knative
    一年增加 1.2w 星,Dapr 能否引领云原生中间件的未来?
    源码解读:KubeVela 是如何将 appfile 转换为 K8s 特定资源对象的
    绘本推荐
    油猴Tampermonkey
    lan蓝tern灯
    6岁叛逆期
    留白
  • 原文地址:https://www.cnblogs.com/conbein/p/3287922.html
Copyright © 2020-2023  润新知