• wordcount复习


    MapReduce的产生

    MapReduce最早是由Google公司研究提出的一种面向大规模数据处理的并行计算模型和方法。Google公司设计MapReduce的初衷主要是为了解决其搜索引擎中大规模网页数据的并行化处理。

    2003年和2004年,Google公司在国际会议上分别发表了两篇关于Google分布式文件系统和MapReduce的论文,公布了Google的GFS和MapReduce的基本原理和主要设计思想。

    可以把MapReduce理解为,把一堆杂乱无章的数据按照某种特征归纳起来,然后处理并得到最后的结果。Map面对的是杂乱无章的互不相关的数据,它解析每个数据,从中提取出key和value,也就是提取了数据的特征。经过MapReduce的Shuffle阶段之后,在Reduce阶段看到的都是已经归纳好的数据了,在此基础上我们可以做进一步的处理以便得到结果

    MapReduce会生成大量的临时文件,为了提高效率,它利用Google文件系统来管理和访问这些文件。

    主要功能

    1)数据划分和计算任务调度

    2)数据/代码互定位

    3)系统优化

    4)出错检测和恢复

    优点

    易于编程:它简单的实现了一些接口,不需要关注太多底层逻辑(如网络协议等),就可以写一个分布式程序。

    良好的扩展性:当计算资源不能得到满足时,通过简单的增加物理机来增强计算能力以及存储能力。

    高容错性:Mapreduce设计的初衷就是部署在廉价的pc机器上,这就要求它具有很高的容错性,比如其中一台机器挂了,通过hadoop的管理,此机器上的任务可以转移到其他节点上运行,且此过程不需要人工参与。

    适合PB级别以上海量数据存储以及上千台服务器集群并发工作

    缺点

    不擅长实时计算:无法像mysql一样在秒级别以内返回结果。

    **不擅长流式计算(并不是不能实现--Spark Streaming):流式计算的输入是动态的,由于mapreduce自身的设计特点使得mapreduce的输入数据是静态的,不能动态化。即使实现了动态数据的输入,因为其返回结果的速度相对慢,所以也不适合。

    不擅长DAG(有向图)式计算:若多个任务存在依赖关系。例如c的输入依赖于b的输出,b的输入依赖于a的输出,而marpduce在执行每一个任务时都会把数据存储到磁盘中,使得程序之间的通信相对慢。

    总结:慢

    写一个MapReduce的一个案例WordCount

    WcMapper.java

     
        import org.apache.hadoop.mapreduce.Mapper;
        import org.apache.hadoop.io.IntWritable;
        import org.apache.hadoop.io.LongWritable;
        import org.apache.hadoop.io.Text;
        import java.io.IOException;
        
        /**前两个泛型为MR框架给mapper程序的输入,输入的对象为一行数据对象,< 行首的偏移量,行的内容>
         * 例如需要处理的源文件为    hello hadoop
         *                       hello flink
         *则此时mapper需要处理的第一个数据对象为0,"hello hadoop"), 0对应LongWritable,“hello hadoop“对应 Text
         *处理完第一个再重复处理第二个。
         *
         * @author xido
        */
        public class WcMapper extends Mapper< LongWritable,Text, Text, IntWritable> {
            private Text word = new Text();
            private IntWritable one = new IntWritable(1);
        
            @Override
        //    重写父类的map方法
        //    Context对象为当前整个mapreduce任务给map的一个输入输出接口,map从Context读取输入处理完输出给Context
            protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        
        //      拿到这一行数据
                String line = value.toString();
        
        //      按照空格切分数据装入一个数组容器
                String[] words = line.split(" ");
        
        //      遍历数组,把单词变成(word,1)的形式交给Context
                for (String word:words) {
        //          原为context.write(new Text(word),new IntWritable(1));
        //          由于大量new对象浪费资源,所以定义了成员变量
                    this.word.set(word);
                    context.write(this.word,this.noe);
                }
            }
        }
        

    Reducer.java

        import org.apache.hadoop.io.IntWritable;
        import org.apache.hadoop.io.Text;
        import org.apache.hadoop.mapreduce.Reducer;
        import java.io.IOException;
        
        /**
         * 得到的数据对象为Context聚合之后的数据:map输出给Context,Context将结果进行聚合
         * 例如 mapper输出的值中 将同key的数据聚合(例 (hello,1) (hello,1)聚合为 (hello,{1,1}(一个Iterable对象))
         * 然后再输出给reducer处理
         */
        public class WcReducer  extends Reducer< Text,IntWritable,Text, IntWritable> {
            private IntWritable total = new IntWritable();
            @Override
            protected void reduce(Text key, Iterable< IntWritable> values, Context context) throws IOException, InterruptedException {
                int sum = 0;
        //      遍历包含n个1的Iterable对象
                for(IntWritable value:values){
        //          此处可以写 sum+=1,但不推荐写1。原因待笔者研究
                    sum+=value.get();
                }
        //        包装结果并输出
                total.set(sum);
                context.write(key,total);
            }
        }
        

    Driver.java

        import org.apache.hadoop.conf.Configuration;
        import org.apache.hadoop.io.IntWritable;
        import org.apache.hadoop.io.Text;
        import org.apache.hadoop.mapreduce.Job;
        import org.apache.hadoop.fs.Path;
        import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
        import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
        import java.io.IOException;
        
        public class WcDriver {
        
            /*
            *前面只是定义了map与reduce的逻辑
            * 但是没有接入MR框架
            *在Driver中配置map与reduce的环境(输入文件输出文件等)
            */
            public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        //     1 获取一个job实例 job即一个mapreduce task
                       Job job =  Job.getInstance(new Configuration());
        
        //     2 设置Driver类路径
                job.setJarByClass(WcDriver.class);
        
        //      3 设置mapper与reducer
                job.setMapperClass(WcMapper.class);
                job.setReducerClass(WcReducer.class);
        
        //      4 设置Mapper与Reducer输出的类型
                job.setMapOutputKeyClass(Text.class);
                job.setMapOutputValueClass(IntWritable.class);
        
        //      设置reducer输出即总输出
                job.setOutputKeyClass(Text.class);
                job.setOutputValueClass(IntWritable.class);
        
        //      5  设置输入输出数据存储的文件夹
        //         执行时Path由main指定
                FileInputFormat.setInputPaths(job, new Path(args[0]));
                FileOutputFormat.setOutputPath(job,new Path(args[1]));
        
        //      6 提交我们的job
                boolean b= job.waitForCompletion(true);
                System.exit(b?0:1);
            }
        }
    

    PS

    1 参考了 百度 以及尚硅谷的hadoop课程及ppt

    2 写(ban)作(yun)匆忙,各位若发现错误请多交流指正

    3 学有余力的同学可以试试 阿里巴巴hadoop笔试

  • 相关阅读:
    MySQL的注入过程
    nmap 扫描器的功能
    用dvwa演示带有用户令牌(user_token)的暴力破解
    在python中安装requests模块
    如何发现struts2漏洞
    vs2017的主题颜色的配置
    在vs上开发linux c++
    linux主机之间的SSH链接
    verilog 实用的小技巧
    verilog 实现DDS
  • 原文地址:https://www.cnblogs.com/xido/p/13839956.html
Copyright © 2020-2023  润新知