Hadoop知识汇总

原理解析

一·YARN调优

1. yarn相关参数解析
1).RM的内存资源配置, 配置的是资源调度相关
RM1:yarn.scheduler.minimum-allocation-mb 分配给AM单个容器可申请的最小内存
RM2:yarn.scheduler.maximum-allocation-mb 分配给AM单个容器可申请的最大内存
注:

  • 最小值可以计算一个节点最大Container数量
  • 一旦设置,不可动态改变

2).NM的内存资源配置,配置的是硬件资源相关
NM1:yarn.nodemanager.resource.memory-mb 节点最大可用内存
NM2:yarn.nodemanager.vmem-pmem-ratio 虚拟内存率,默认2.1
注:

  • RM1、RM2的值均不能大于NM1的值
  • NM1可以计算节点最大最大Container数量,max(Container)=NM1/RM1
  • 一旦设置,不可动态改变

3).AM内存配置相关参数,配置的是任务相关
AM1:mapreduce.map.memory.mb 分配给map Container的内存大小
AM2:mapreduce.reduce.memory.mb 分配给reduce Container的内存大小

  • 这两个值应该在RM1和RM2这两个值之间
  • AM2的值最好为AM1的两倍
  • 这两个值可以在启动时改变
    AM3:mapreduce.map.java.opts 运行map任务的jvm参数,如-Xmx,-Xms等选项
    AM4:mapreduce.reduce.java.opts 运行reduce任务的jvm参数,如-Xmx,-Xms等选项
    注:
  • 这两个值应该在AM1和AM2之间
    4).RM的CPU资源配置, 配置的是资源调度相关
    yarn.scheduler.minimum-allocation-vcores:最小可申请CPU数,默认是1
    yarn.scheduler.maximum-allocation-vcores:最大可申请CPU数,默认是4
    2.关于Container
    (1)Container是YARN中资源的抽象,它封装了某个节点上一定量的资源(CPU和内存两类资源)。它跟Linux Container没有任何关系,仅仅是YARN提出的一个概念(从实现上看,可看做一个可序列化/反序列化的Java类)。
    (2)Container由ApplicationMaster向ResourceManager申请的,由ResouceManager中的资源调度器异步分配给ApplicationMaster;
    (3)Container的运行是由ApplicationMaster向资源所在的NodeManager发起的,Container运行时需提供内部执行的任务命令(可以使任何命令,比如java、Python、C++进程启动命令均可)以及该命令执行所需的环境变量和外部资源(比如词典文件、可执行文件、jar包等)。
    另外,一个应用程序所需的Container分为两大类,如下:
    (1) 运行ApplicationMaster的Container:这是由ResourceManager(向内部的资源调度器)申请和启动的,用户提交应用程序时,可指定唯一的ApplicationMaster所需的资源;
    (2)运行各类任务的Container:这是由ApplicationMaster向ResourceManager申请的,并由ApplicationMaster与NodeManager通信以启动之。
    以上两类Container可能在任意节点上,它们的位置通常而言是随机的,即ApplicationMaster可能与它管理的任务运行在一个节点上。
    Container是YARN中最重要的概念之一,懂得该概念对于理解YARN的资源模型至关重要,望大家好好理解。
    注意:map/reduce task是运行在Container之中的,所以上面提到的mapreduce.map(reduce).memory.mb大小都大于mapreduce.map(reduce).java.opts值的大小。
    二·HDFS
    三·MapReduce

代码实操

一·scala实现MapReduce的wordcount

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

class MRmap extends Mapper[LongWritable, Text, Text, IntWritable]{
  override def map(key: LongWritable, value: Text, context: Mapper[LongWritable, Text, Text, IntWritable]#Context): Unit = {
    val words = value.toString
    val arr = words.split(",")
    for (x <- arr) {
      context.write(new Text(x), new IntWritable(1))
    }
  }
}

class MRreduce extends Reducer[Text, IntWritable, Text, IntWritable] {
  def reduce(key: Text, values: Iterable[IntWritable], context: Reducer[Text, IntWritable, Text, IntWritable]#Context): Unit = {
    //统计个数
    var cnt:Int=0
    for (x :IntWritable <- values){
      cnt +=x.get()
    }
    context.write(key,new IntWritable(cnt))
  }
}

object MR extends Configured with Tool{
  override def run(strings: Array[String]): Int = {
    val configuration = new Configuration()
    //configuration.set("fs.defaultFS","hdfs://work01:8020")

    val job = Job.getInstance(configuration)
    job.setJarByClass(this.getClass)
    job.setJobName("wordcount")

    //map.reduce.combiner
    job.setMapperClass(classOf[MRmap])
    job.setReducerClass(classOf[MRreduce])
    job.setCombinerClass(classOf[MRreduce])
    job.setMapOutputKeyClass(classOf[Text])
    job.setOutputValueClass(classOf[IntWritable])

    //输入 输出
    FileInputFormat.addInputPath(job,new Path("C:\\Users\\yxiong02\\Desktop\\data\\13320-5419-tags.csv"))
    FileOutputFormat.setOutputPath(job,new Path("C:\\Users\\yxiong02\\Desktop\\data\\output"))

    val bool:Boolean = job.waitForCompletion(true)
    if (bool) 0 else 1
  }

  def main(args: Array[String]): Unit = {
    run(Array())
  }
}

二·修改文件输出名
写一个类继承TextOutputFormat,重写setOutputName方法,然后在driver类里指定一个输出类就ok了

//指定输出名的输出类
class MyOut extends TextOutputFormat {

    protected static void setOutputName(JobContext job, String name) {
        job.getConfiguration().set(BASE_OUTPUT_NAME, name);
    }
}

//在driver类加一句
MyOut.setOutputName(job, strs);
//把strs修改为你需要的名字就好了

三·指定reduce输出
写一个分区类继承Partitioner<Text,Text>,重写getPartitoner方法

class XyyPatitioner extends Partitioner<Text,Text> {

    public int getPartition(Text key, Text value, int num) {
        if(value.toString().contains("chengdu")){
            return 1;
        }else if(value.toString().contains("hangzhou")){
            return 2;
        }else if(value.toString().contains("nanjing")){
            return 3;
        }else if(value.toString().contains("zhengzhou")){
            return 4;
        }else {
            return 0;
        }
    }
}

//driver类加两行
job.setPartitionerClass(XyyPatitioner.class);
job.setNumReduceTasks(num);//设置reduce个数

getPartition()方法有三个形参,源码中key、value分别指的是Mapper任务的输出,numReduceTasks指的是设置的Reducer任务数量,默认值是1


这里只是做个笔记,顺便骗一骗阅读量,哈哈哈哈,原谅我的厚颜无耻。大佬们有什么交流的可以随意留言。
(未完待续)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值