Hadoop(五)Yarn

一.Yarn基本理论

1.Yarn架构

Resource Manager

  • 整个集群资源的统一管理者
  • 处理客户端请求
  • 监控Node Manager
  • 资源的分配和调度

Node Manager

  • 单个节点服务器的资源管理者
  • 处理来自RM和AM的命令

App Mstr

  • 单个任务运行的管理者
  • 为应用程序申请资源并分配任务
  • 任务的监控和容错

Container

  • 相当于一台独立服务器,里面有任务运行所需要的资源,比如CPU、磁盘、网络等,运行MapTask、ReduceTask等

在这里插入图片描述

2.Yarn工作机制

1.job.waitForCompletion()产生YarnRunner,和RM申请运行一个应用,RM同意后返回一个路径,告知应用将资源(切片、job.xml、jar包)提交到HDFS上

2.RM将用户的请求初始化为一个Task,放到任务队列里

3.其中一个NodeManager领取到Task任务,该NodeManager创建容器Container生成进程MapReduceAppMaster,Container从HDFS上拷贝资源到本地,并且分析切片信息

3.MapReduceAppMaster向RM申请运行MapTask资源(如果多个MapTask,将根据情况运行在不同NodeManager)

4.MapReduceAppMaster向接收到任务的NodeManager发送程序启动脚本,NodeManager分别启动MapTask,MapTask对数据分区排序

5.MapReduceAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask

6.ReduceTask向MapTask获取相应分区的数据

7.程序运行完毕后,MR会向RM申请注销自己

注:App Mstr、Map Task、Reduce Task都是运行在Container中

3.Yarn调度器

目前,Hadoop作业调度器主要有三种:FIFO、容量(Capacity Scheduler)和公平(Fair Scheduler)。Apache Hadoop3.1.3默认的资源调度器是Capacity Scheduler

先进先出调度器(FIFO)

FIFO调度器(First In First Out):单队列,根据提交作业的先后顺序,先来先服务,生产环境一般不用

容量调度器(Capacity Scheduler)

在这里插入图片描述

  • 多队列FIFO
  • 以队列为单位划分资源,每个队列设定一定比例的资源最低保证使用上限,比如总资源只有60%资源,那么每一个队列都应该分配到一定资源(这里的资源指的内存资源)
  • 规定每个用户对每一个队列只有一定的资源使用上限,以防止资源滥用
  • 当一个队列的资源有剩余时,可暂时将剩余资源共享给其他队列,但是该队列有新的作业时,资源必须归还
  • 每一个队列会对前几个符合资源要求的应用分配资源,比如上述的Q1队列,作业A需要20%,作业B需要25%,那么该队列会把资源分给A和B

容量调度器资源分配算法

队列级别:首先优先选择资源占用最低的队列分配资源,如上面的Q2队列

作业级别:设置优先级,按照优先级;否则按照提交时间顺序

容器级别:设置优先级,按照优先级;否则按照数据本地性原则,任务和数据近的优先

公平调度器

  • 多队列FIFO
  • 以队列为单位划分资源,每个队列设定一定比例的资源最低保证和使用上限,比如只有60%资源,那么每一个队列都应该分配到资源
  • 规定每个用户对每一个队列只有一定的资源使用上限,以防止资源滥用
  • 当一个队列的资源有剩余时,可暂时将剩余资源共享给其他队列
  • 每个队列公平分布资源,如队列有20%资源,4个作业,每一个任务都会分配到5%资源

公平调度器资源分配算法

队列级别:二次分配:第一次绝对公平分,第二次资源多的队列再给少的队列,实现分配

作业级别

  • 不加权 第一次绝对公平,第二次将多的再平分分给少的,第三次再将多的再平分分给少的,直到没有空闲资源
  • 加权 根据权重分资源 多的给少的,循环直到没有空闲资源
    在这里插入图片描述

DRF(dominant resource fairness)

通常的资源都是单一的标准,例如只考虑内存的情况(YARN默认情况),但是多数情况是多种资源的复合,从而难以衡量两个应用应该分配的资源比例,我们就用DRF来决定如何调度,即看哪个资源需求占主导

4.Yarn常用命令

yarn application查看任务

列出所有的Application

yarn application -list

根据Application状态过滤

yarn application -list -appStates XXX(XXX - ALL、NEW、NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED)

杀死程序

yarn application -kill application-id

yarn logs查看日志

查询Application日志

yarn logs -applicationId <ApplicationId>

查询Container日志

yarn logs -applicationId <ApplicationId> -containerId <ContainerId>

yarn applicationattempt查看尝试运行的任务

列出所有Application尝试的列表

yarn applicationattempt -list <ApplicationId>

打印ApplicationAttemp状态

yarn applicationattempt -status <ApplicationAttemptId>

yarn container查看容器

列出所有Container

yarn container -list <ApplicationAttemptId>

打印Container状态

yarn container -status <ContainerId>

只有在任务跑的途中才能看到container的状态

yarn node查看节点状态

列出所有节点

yarn node -list -all

yarn rmadmin更新配置

加载队列配置

yarn rmadmin -refreshQueues

yarn queue查看队列

打印队列信息

yarn queue -status <QueueName>
5.Yarn参数配置

**RM相关**

二 .tool接口

一个tool 接口用于支持处理普通的命令行参数

比如,我们在hadoop集群上输入命令行

yarn jar wc.jar com.gzhu.yarn.YarnDriver wordcount -Dxx /input /output

此时hadoop集群会把参数xx作为输入路径,/input作为输出路径,这样就会报错输出路径存在,为了让hadoop正确识别到输入路径和输出路径是第二个参数和第三个参数,tool接口的作用就来了

在这里插入图片描述

YarnDriver

package com.gzhu.yarn;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.util.Arrays;

public class YarnDriver {
    private static Tool tool;
    public static void main(String[] args) throws Exception {
        // 创建配置信息
        Configuration configuration = new Configuration();

        switch (args[0]){
            case "wordcount":
                tool = new YarnTool();
                break;
            default:
                throw new RuntimeException("no no no");
        }

        int run = ToolRunner.run(configuration,tool, Arrays.copyOfRange(args,1,args.length));

        System.exit(run);
    }
}

YarnTool

package com.gzhu.yarn;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;

import java.io.IOException;

public class YarnTool implements Tool {
    private Configuration conf;
    @Override
    public int run(String[] args) throws Exception {
        // 1.获取job
        Job job = Job.getInstance(conf);

        // 2.设置jar路径
        job.setJarByClass(YarnDriver.class);

        // 3.关联mapper和reducer
        job.setMapperClass(YarnTool.WorldCountMapper.class);
        job.setReducerClass(YarnTool.WorldCountReduce.class);

        // 4.设置map输出的kv类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        // 5.设置最终输出的kv类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        boolean b = job.waitForCompletion(true);
        return b ? 0 : 1;
    }

    @Override
    public void setConf(Configuration configuration) {
        this.conf = configuration;
    }

    @Override
    public Configuration getConf() {
        return conf;
    }

    // mapper
    public static class WorldCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
        private Text text = new Text();
        private IntWritable intWritable = new IntWritable(1);
        @Override                  // 这里的value是每一行数据
        protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
            // 1.根据原始数据获取一行,转换成字符串,例如 kun kun kun
            String string = value.toString();

            // 2.切割每一行单词  [kun,kun,kun]
            String[] words = string.split(" ");

            // 3.循环写出,每一个kun都为1 K-V kun-1,Mapper阶段不汇总,所以每一个都是1
            for (String word : words) {
                // 将String类型转换成Text类型
                text.set(word);
                // write里面的参数为输出的两个参数类型 Text, IntWritable
                // 这里输出三个kun-1
                context.write(text,intWritable);
            }
        }
    }
    // reduce
    public static class WorldCountReduce extends Reducer<Text, IntWritable,Text,IntWritable> {
        private IntWritable intWritable = new IntWritable();
        @Override
        // key代表每一个key,例如Kun,values是一个集合,里面存的是key对应的V值
        protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
            int sum = 0;

            // 将每一个Key对应的value汇总
            for (IntWritable value : values) {
                sum += value.get();
            }
            intWritable.set(sum);

            context.write(key,intWritable);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jumanji_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值