Hadoop基础(十) ---split切片分析,counter,开启历史服务器,远程调试,Word Count,YARN组成框架和工作流程分析

一、输入的split,输入切分
--------------------------------------------
    1.获取切分块单元size,一般取自定义最小值和blocksize中的最小值
        long splitsize = Math.max(minSize, Math.min(maxSize, blockSize));
        其中,minsize = mapreduce.input.fileinputformat.split.minsize
            blocksize = hdfs.blocksize
            maxsize = mapreduce.input.fileinputformat.split.maxsize 默认为long_max
        所以,一般 splitsize = Math.max(minSize,blocksize)
        
    2.代码设置切片大小
        1.FileInputFormat.setMaxInputSplitSize(job,30);
        2.job.getConfiguration().setLong(FileInputFormat.SPILT_MINSIZE,30);

二、在名称节点上开启历史服务器,查看以往的作业
-----------------------------------------------
    1.在名称节点上执行命令
        $> mr-jobhistory-daemon.sh start historyserver
    
        
三、查看集群的配置项的值
------------------------------------------------
    1.hdfs getconf -congkey dfs.blocksize
    
    
四、counter计数器
--------------------------------------------------
    1.counter名称长度有限,不能太长,否则会被截断
    
    2.setup和cleanup阶段,只执行一次,而且多个map可能使用同一个jvm来运行
    
    3.map作业每次处理一行,即使split大小小于单个行的长度,也不会导致行丢失
    
    4.每个job允许用户自定义的counter上限是120,可以进行修改
        [mapred-site.xml] mapreduce.jpb.counters.limit的值1024


五、MR作业Job属性设置
-----------------------------------------------
    1.设置配置文件gConfiguration的值:例如输入切片最大值和最小值,此处的变量覆盖掉系统的配置变量
        job.getConfiguration().setLong(FileInputFormat.SPILT_MINSIZE,30);
        job.getConfiguration().setLong(FileInputFormat.SPILT_MAXSIZE,30);

    2.设置reduce任务的数量
        job.setNumReduceTasks(2);
        
    3.设置最大的map/reduce任务数量
        job.setMaxMapAttempts(120);
        job.setMaxReduceAttempts(120);
        
    4.设置合成类,对map的输出进行统一化的进一步处理,从而将简化的结果作为reduce的输入,减少网络传输的数据量
        job.setCombinerClass(MyReducer.class);    
六、自定义分区类
-------------------------------------------------

/**
 * 自定义分区器
 * @author Administrator
 *
 */
public class MyPartitioner extends Partitioner<Text, IntWritable>{

    @Override
    public int getPartition(Text key, IntWritable value, int numPartitions) {
        
        return 0;
    }

}


七、远程调试-- 查看集群的RM和NM
--------------------------------------------------
    1.确保RM是停掉的。如果没有,那么停掉ResourceManager(NM一样)
        $> yarn-daemon.sh stop resourcemanager
        
    2.设置环境变量
        调试RM设置:$> export YARN_RESOURCEMANAGER_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
        调试NM设置:$> export $HADOOP_CLIENT_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"

        注意:这个环境变量设置好之后,就表示之后所有的java app都会默认启动远程调试模式,所以,调试完,记得将变量置空
        如果不想启用,那么在启动java app之前,将此环境变量再次设置为空即可
        $> export YARN_RESOURCEMANAGER_OPTS =
        $> export $HADOOP_CLIENT_OPTS =
        
    3.启动resourcemanager(NM一样)
        $> yarn-daemon.sh start resourcemanager
        
    4.打开eclipse --> run --> Debug configure --> remote java application
        --> 配置好ip和端口号 --> Debug开始调试(记得提前打好断点)        
    
    
八、MRAppMaster
---------------------------------------------------
    1.在单独的jvm中,创建一个子进程,来运行MRtasks
    
    2.创建的子进程,继承了MRAppMaster的配置信息
    

九、Word Count案例
----------------------------------------------------**************************************
1.App入口函数类
**************************************

public class MyApp {
    

    public static void main(String[] args) {
            
        try 
        {            
            Job job = Job.getInstance();
        
            job.setJarByClass(MyApp.class);
        
            job.setJobName("Word Count");
        
            FileInputFormat.addInputPath(job, new Path(args[0]));
    
            FileOutputFormat.setOutputPath(job, new Path(args[1]));
            
            //指定Map类
            job.setMapperClass(MyMapper.class);
            
            //指定Reduce类
            job.setReducerClass(MyReducer.class);

            job.setOutputKeyClass(Text.class);
        
            job.setOutputValueClass(IntWritable.class);

            job.waitForCompletion(true);            
        
        } 
        catch (Exception e) 
        {    
            e.printStackTrace();
        } 
        
    }
    
}


**************************************
2.Map类
**************************************

public class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable>{

    Map<String,Integer> map = null;

    @Override
    protected void setup(Mapper<LongWritable, Text, Text, IntWritable>.Context context)
            throws IOException, InterruptedException {
        
        map = new HashMap<String,Integer>();
    
    }
    
    /**
     * map
     */
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
            throws IOException, InterruptedException {
        
        
        context.getCounter("mapper", MyUtils.getCounterName(this, "map")).increment(1);
        
        //获取一行数据
        String line = value.toString();        
        //获取单词
        String [] words = line.split("\\s+");
        
        
        for(String s : words)
        {
            if(map.containsKey(s))
            {
                int v = map.get(s);
                v = v + 1;
                map.remove(s);
                map.put(s, v);
            }
            else
            {
                map.put(s, 1);
            }            
        }
    }
    
    
    /**
     * cleanup
     */
    @Override
    protected void cleanup(Mapper<LongWritable, Text, Text, IntWritable>.Context context)
            throws IOException, InterruptedException {
        context.getCounter("mapper", MyUtils.getCounterName(this, "cleanup")).increment(1);
        
        Set<String> keySet = map.keySet();
        for (String k: keySet) {
            int v = map.get(k);            
            context.write(new Text(k), new IntWritable(v));
        }    
    }
    
}

**************************************
3.Reduce类
**************************************

public class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable>{


    @Override
    public void reduce(Text key, Iterable<IntWritable> values, Context context)
            throws IOException, InterruptedException 
    {
        context.getCounter("reduce", MyUtils.getCounterName(this, "reduce")).increment(1);
    
        int count = 0;
        for (IntWritable i : values) {
            int v = i.get();
            count += v;
        }
                
        context.write(key, new IntWritable(count));
    }
        
}

十、YARN的基本组成框架
-------------------------------------------------
    1.ResourceManager(RM):全局资源管理器
        a.全局应用程序管理器
        负责整个RM系统的所有应用程序的管理工作,包括应用程序的提交,状态的查询,任务失败的重启等。
        可以理解为大脑,处理中枢,负责汇总所有ApplicationMaster的工作
        注意:因为一个集群只有一个RM,只有一个应用程序管理器,但是可能会提交很多任务,产生很多个ApplicationMaster
        
        b.调度器
        仅仅负责资源的调度,仅仅根据ApplicationManager(AM)的指示,去分配和调度资源。
        
    2.ApplicationMaster(AM):单个应用程序主管(每个MR任务都有一个单独的AM)
        a.用户每提交一个MR任务,就会产生一个AM,对任务进行管理
        
        b.主要功能包括
            1.实时与全局应用程序管理器进行通信,发送状态信息等
            2.采用轮询方式,通过RPC协议,向RM申请和获取可用资源容器(container)
            3.当已经分配好资源容器,便与被分配资源容器的NodeManager进行通信,要求NodeManager执行Map/Reduce任务
            并实时的获取任务的执行状态
            4.当NodeManager执行任务失败的时候,重启任务
    
    3.NodeManager(NM)
        a.NM是每一个节点上的资源和任务管理器,负责执行RM调度器发送的开辟资源容器指令以及AM发送的各种指令
        b.主动向AM汇报各个MR作业的状态
    
    4.Container:可用资源容器
        a.是一个抽象概念,包括为了执行任务所必须的环境:内存,CPU,硬盘,网络等
        b.每个AppMR任务都会有一个container
        c.是一个动态的资源,实时根据RM的分配而来
        
        
十一、YARN的工作流程分析
------------------------------------------------
    1.Cilent提交 Job
    
    2.全局资源管理器 开启 全局应用程序管理器(为了方便,下面的RM均代表 全局应用程序管理器) 和 资源调度器
    
    3.RM(全局应用程序管理器)在某一个节点上开启ApplicationMaster(AM),负责管理这个Job
    
    4.AM 首先向RM进行注册,构建通信,然后采用轮询方式,通过PRC协议,向RM申请和领取任务所必须的资源Container
    
    5.RM接收到AM的请求,命令调度器分配资源。
    
    6.调度器分配资源,分配好之后,RM告知AM分配好的资源位置和属性等信息
    
    7.AM根据资源的位置,找到节点上的NodeManager,与之进行通信,要求NM启动任务
    
    8.NM 为任务设置环境,开始执行任务(Map或者Reduce任务),并及时的向AM汇报各个任务状态等信息
    
    9.任务完成后,AM向RM注销并关闭自己


 

猜你喜欢

转载自blog.csdn.net/xcvbxv01/article/details/82153173