MapReduce学习总结

MapReduce计算过程

  • 全流程

  • 文件读取阶段

    MapReduce默认是Text读取方式,即一行一行读取文本内容,以读取数据的偏移量,每行文本内容组成”KEY-VALUE“键值对输送给下一阶段。

    PS:如果指定一个文件夹,则会读取文件夹下所有文件;如果指定文件,则只会读取此文件。

  • Map阶段

    在Map阶段,我们可以获取每个MapTask任务文件读取所返回的“KEY-VALUE”键值对,我们可以根据不同的业务逻辑需求将其重新切分组合,形成新的键值对写入上下文中,进入下一阶段。

    此步需要继承Mapper,重写map方法进行业务逻辑的重写。

  • 分区

    我们可以自定义条件为每条数据打上TAG标记,将来进行Reduce操作时,不同的ReduceTask会拉取某一TAG标记的数据,进行数据的聚合。

    如果需要进行分区操作,继承Partitioner重写getPartition方法。

  • 排序

    排序步骤其实分为两次,一次是在Map阶段,在数据分区打上TAG标志之后,会进行一次局部排序;另一次是在Reduce阶段,数据汇总之后,数据会进行一次全排序。

    如果需要进行排序,则需要自己编写一个JAVABEAN类实现WritableComparable重写序列化方法(write、read)、排序方法(compareTo)。排序方法返回的int值大于0则代表升序,小于0为降序。

    PS:排序是根据KEY值进行排序的,所以Map阶段所输出的格式的KEY必须是需要进行比较数据(一般为自定义的BEAN类)。

  • 规约

    为了减少网络传输过程中的数据冗余,可以先在Map阶段向Reduce阶段传输之前,先进行一次Reduce操作,进行冗余数据的局部合并。

    如果需要进行规约操作,则需要继承Reduce重写reduce方法。

  • 分组

    判断是否将同一Reduce内的数据聚合在同一组。

    如果需要进行进行分组操作,则需要继承WritableComparator并重写compare方法。

    PS:此阶段以上阶段,所有操作均在Hadoop集群中运行,不在同一机器上。

  • Reduce阶段

    接受Map阶段汇总的数据,按照上述的分组操作进行分组(默认为将同一KEY的数据聚合在同一组)。

    此阶段需要继承Reduce,并重写reduce方法。

  • 文件输出阶段

    根据输出格式(默认是TextOutputFormat),保存到设置路径。

    PS:保存路径不可存在,如果输出路径存在,程序则会报错。

模板代码

  • Bean

    public class FlowBean implements WritableComparable<FlowBean> {
    
    
        private Integer upFlow=0;
        private Integer downFlow=0;
        private Integer upCountFlow=0;
        private Integer downCountFlow=0;
    
        @Override
        public String toString() {
            return upFlow +
                    "\t" + downFlow +
                    "\t" + upCountFlow +
                    "\t" + downCountFlow;
        }
    
        public Integer getUpFlow() {
            return upFlow;
        }
    
        public void setUpFlow(Integer upFlow) {
            this.upFlow = upFlow;
        }
    
        public Integer getDownFlow() {
            return downFlow;
        }
    
        public void setDownFlow(Integer downFlow) {
            this.downFlow = downFlow;
        }
    
        public Integer getUpCountFlow() {
            return upCountFlow;
        }
    
        public void setUpCountFlow(Integer upCountFlow) {
            this.upCountFlow = upCountFlow;
        }
    
        public Integer getDownCountFlow() {
            return downCountFlow;
        }
    
        public void setDownCountFlow(Integer downCountFlow) {
            this.downCountFlow = downCountFlow;
        }
    
        @Override
        public void write(DataOutput out) throws IOException {
            out.writeInt(upFlow);
            out.writeInt(downFlow);
            out.writeInt(downCountFlow);
            out.writeInt(upCountFlow);
        }
    
        @Override
        public void readFields(DataInput in) throws IOException {
            this.upFlow=in.readInt();
            this.downFlow=in.readInt();
            this.downCountFlow=in.readInt();
            this.upCountFlow=in.readInt();
        }
    
        @Override
        public int compareTo(FlowBean o) {
            return o.getUpFlow()-this.upFlow;
        }
    }
    
    
  • Map

    public class FlowSortMapper extends Mapper<LongWritable, Text,FlowBean,Text> {
    
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String[] split = value.toString().split("\t");
            FlowBean flowBean = new FlowBean();
            flowBean.setUpFlow(Integer.parseInt(split[1]));
            flowBean.setDownFlow(Integer.parseInt(split[2]));
            flowBean.setUpCountFlow(Integer.parseInt(split[3]));
            flowBean.setDownCountFlow(Integer.parseInt(split[4]));
            context.write(flowBean,new Text(split[0]));
    
        }
    }
    
  • Reduce

    public class FlowSortReduce extends Reducer<FlowBean,Text,Text,FlowBean> {
    
    
        @Override
        protected void reduce(FlowBean key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            for(Text value:values){
                context.getCounter("AllCount","MyAllCount").increment(1);
                context.write(value,key);
            }
      
    
  • JobMain

    public class JobMain extends Configured implements Tool {
        //定义一个job任务
        @Override
        public int run(String[] args) throws Exception {
            Job job = Job.getInstance(super.getConf(), "fc");
            //设置输入类型
            job.setInputFormatClass(TextInputFormat.class);
    //        job.setJarByClass(JobMain.class);
            //设置文件路径
            TextInputFormat.addInputPath(job, new Path("hdfs://192.168.2.135:8020/laow/part-r-00000"));
    //        TextInputFormat.addInputPath(job,new Path("file:///D:\\a.txt"));      //本地执行
            //设置访问用户名
    //        job.setUser("root");
    
            //设置Map阶段的类
            job.setMapperClass(FlowSortMapper.class);
            //设置map阶段key类型
            job.setMapOutputKeyClass(FlowBean.class);
            //设置map阶段value类型
            job.setMapOutputValueClass(Text.class);
    
            //设置Reduce阶段的类
            job.setReducerClass(FlowSortReduce.class);
            //设置reduce阶段的key类型
            job.setOutputKeyClass(Text.class);
            //设置reduce阶段的value类型
            job.setOutputValueClass(FlowBean.class);
    
            //设置输出类型
            job.setOutputFormatClass(TextOutputFormat.class);
            //设置输出路径
            Path path = new Path("hdfs://192.168.2.135:8020/laow1/");
            FileSystem fs = FileSystem.get(new URI("hdfs://192.168.2.135:8020/"), new Configuration(), "root");
            if (fs.exists(path)) {
                fs.delete(path, true);
            }
            TextOutputFormat.setOutputPath(job, path);
    //        TextOutputFormat.setOutputPath(job,new Path("file:///D:\\hadoop\\"));     //本地执行
            //等待运行结束
            boolean b = job.waitForCompletion(true);
    
            return b ? 0 : 1;
        }
    
        public static void main(String[] args) throws Exception {
            Configuration configuration = new Configuration();
            //启动job任务
            int run = ToolRunner.run(configuration, new JobMain(), args);
            System.exit(run);
        }
    }
    

Maven依赖

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.12.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
        </dependency>


<!--        Hadoop-->
        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.5</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-mapreduce-client-core -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.5</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-core -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-core</artifactId>
            <version>1.2.1</version>
        </dependency>

    </dependencies>
posted @ 2021-02-02 23:02  公鸡不下蛋  阅读(482)  评论(0编辑  收藏  举报