HADOOP-MapReduce学习(一、MR介绍、MR运行)

643 阅读4分钟

一.MR框架介绍

1.mr就指的是MapReduce,首先它是一种编程思想,其次是一个分布式运算框架。spark、flink都市分布       式运算框架,便于将我们的数据运算开发成一个分布式运算程序。
2.M指的就是Map,map的功能就是读原始数据,映射成key-value
  R指的就是reduce,把key相同的进行分组,然后合并,进行聚合运算
3.框架中,对map阶段的程序实现是maptask
    maptask的主要任务
    (1)**读取数据**,默认读取一行
    (2)每读取一行,**调用用户自定义Mapper的map方法进行分组**
    (3)收集map方法返回的键值对,对数据进行分区
  框架中,对reduce阶段的程序主要实现是reduceTask
    reducetask的主要任务
    (1)去map返回的存储结果中拉取数据,**拉取自己负责分区的数据**合并
    (2)**调用用户的自定义的reduce方法做聚合**运算
    (3)收集reduce方法返回的key  value,写在目标存储文件,默认是hdfs

二.一个简单的mapreduce程序(单词统计)

1.要自定义一个Mapper类      
/**
 * LongWritable表示调用maptask返回给我们的key的类型
 * Text表示maptak返回我们的value值类型,默认是Text
 * Text表示调用我们重写的map方法返回的key的类型,单词作为key,定义为Text类型
 * IntWritable表示我们要统计的单词的个数,定义为int类型
 */
public class WcMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] words = value.toString().split(" ");
        for (String word : words) {
            context.write(new Text(word),new IntWritable(1));
        }
    }
}
2.要自定义一个Reducer类
/**
 * Text表示maptask返回的key的类型
 * IntWritable表示maptask返回的value的类型
 * Textreducetask要输出的key的类型
 * IntWritable表示reducetask要返回的value的类型
 */
public class WcReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> iter, Context context) throws IOException, InterruptedException {
        int count = 0;
        for (IntWritable v : iter) {
            count += v.get();
        }
//        Iterator<IntWritable> iterator = iter.iterator();
//        while (iterator.hasNext()){
//            IntWritable v = iterator.next();
//            count += v.get();
//        }
        context.write(key,new IntWritable(count));

    }
}

3.定义一个MRAppMaster类,用于启动job
public class MrAppMaster {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        // 创建一个job
        Job job = Job.getInstance(conf);
        // 指定要运行的map类和reduce类 
        job.setMapperClass(WcMapper.class);
        job.setReducerClass(WcReducer.class);
        // 指定map的输出key  value 类型和reduce的key  value输出类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        // 设置输入输出数据路径
        FileInputFormat.setInputPaths(job,new Path("E:\\test\\b.txt"));
        FileOutputFormat.setOutputPath(job,new Path("E:\\test\\out"));
        //  设置读数据格式是TextInputFormat,设置写数据格式TextOutputFormat
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        // 启动job
        job.waitForCompletion(true);
    }
}

三.一些要用到的概念介绍(为下面的内容准备)

resourcemanager的功能:
    1.处理客户端请求
    2.监控nodemanager
    3.启动或者监控一个Application
    4.资源分配与调度
nodemanager的功能
    1.管理单个节点的资源
    2.处理ResourceManager和MRAppMaster的请求
容器的概念:nodemanager会把服务器上的资源分成N多个虚拟容器,相当于本地的N多个虚拟机

四.YRAN的工作机制(其实就是maptask运行的声明周期)

mapreduce的运行是由yarn控制的,我们要先了解yarn的工作机制
1.客户端启动
2.向resourcemanager申请运行一个appliction
3.resourcemanager返回一个jobid,返回一个资源路径
4.客户端会把job.jar  job.xml   job.split放在此路径下
    job.jar------客户端会遍历资源路径,对资源路径进行切片,如果一个文件大于128*1.1,则切成一片(每片大小为128M)。继续判断剩余的文件是否大于128*1.1,得到一个FileSplit对象,放在ArrayList中,再转成数组,序列化成job。split
    job.xml------序列化job对象,读取Configuration的配置,输出成job.xml
    job.jar------如果程序运行在集群上,输出运行的jar包到资源路径下,形成job.jar
5.客户端申请一个MRAppMaster容器(1.5G +1core)
  但是单位是以1G为单位
6.RM(resourcemanager)查看空闲的容器任务队列,分配任务去创建MRAppMaster容器(2G 1core)
7.空闲的容器都会心跳检测,领取任务并创建MRAppMaster容器,把资源路径下的文件拷贝到自己容器的工作目录下 
8.客户端发送shell指令到MRAppMaster,java -cp  ..MrAppMaster  包名    去创建一个进程,启动MRAppMater容器
9.MRAppMaster根据job.split计算出需要多个个MapTask容器,想RM申请
10.RM查看空闲的容器任务队列,指派任务,nodemanager会向RM心跳检测,查看是否有属于自己的任务,
   领取属于自己的任务,创建容器
11.MRAppMaster发送shell指令给maptask所在的容器,启动一个yarnchild进程
12.等任务执行完毕后nodemanager会释放资源,心跳向Resourcemanager汇报自己的容器处于空闲状态,向MRAppMaster汇报自己的任务完成
MR等待所有的任务完成以后,会想客户端汇报自己任务完成,向RM汇报自己任务完成,处于空闲状态

nodemanager会定时向resourcemanger发送心跳检测
    1.证明自己还存活
    2.汇报自己的使用情况,有多少个空闲的容器
    3.领取属于自己的任务      

有不正确的地方欢迎指出,感谢!