• 【大数据】MapTask并行度和切片机制


    一. MapTask并行度决定机制
    maptask的并行度决定map阶段的任务处理并发度,进而影响到整个job的处理速度
    那么,mapTask并行实例是否越多越好呢?其并行度又是如何决定呢?
    1.1 mapTask并行度的决定机制
    一个job的map阶段并行度由客户端在提交job时决定
    而客户端对map阶段并行度的规划的基本逻辑为:
    将待处理数据执行逻辑切片(即按照一个特定切片大小,将待处理数据划分成逻辑上的多个split),然后每一个split分配一个mapTask并行实例处理
    (3)注意:block是HDFS上物理上存储的存储的数据,切片是对数据逻辑上的划分。两者之间没有关系。即使hdfs上是128M存储,Mapreduce也会切片,只是默认切片也是128M。也可以非128M切片,如100M,多余的部门由框架内部处理和其他结点进行拼接切片。因为切片决定了给其分配mapTask进程数量。
    (4)在HDFS上,map默认运算切片大小是128M,但如果是本地运行的话,maP默认切片大小是32M.。maptask 和reducetask其实都框架下的一个类。
     
    这段逻辑及形成的切片规划描述文件,由FileInputFormat实现类的getSplits()方法完成,其过程如下图:
    二:InputFormat数据切片机制
     主要有两个方法:getsplit(),客户端用来切片。
                      creatRecordReader()MR用来读数据
       1.FileInputFormat切片机制(在提交yarn前已完成,客户端完成)
            注解:FileInputFormat继承与InputFormat类,都是mapreduce包下的类。归其管理
            其余的常用类,如TextInputFormat和CombinInputFormat都是FileInputFormat的子类。
     1、切片定义在InputFormat类中的getSplit()方法
     2、FileInputFormat中默认的切片机制:
         1.简单地按照文件的内容长度进行切片
         2.切片大小,默认等于block大小(这样如果有很多小文件时,就会产生很多切片,造成很多个maptask,降低系统性能)
         3.切片时不考虑数据集整体,而是逐个针对每一个文件单独切片
    比如待处理数据有两个文件:
    file1.txt    320M
    file2.txt    10M
     
    经过FileInputFormat的切片机制运算后,形成的切片信息如下: 
     
    file1.txt.split1--  0~128
    file1.txt.split2--  128~256
    file1.txt.split3--  256~320
    file2.txt.split1--  0~10M
     
    3、FileInputFormat中切片的大小的参数配置
     
    2.FileInputFormat源码解析(input.getSplits(job))从job.waitforComplecation开始断点,直到提交到yarn上。
    (1)找到你数据存储的目录。(可以是目录,多个文件同时进行统计,然后将统计结果装载到一个文件或者多个文件里。。也可以单独统计分析1个文件。)
           (2)开始遍历处理(规划切片)目录下的每一个文件
           (3)遍历第一个文件ss.txt
                  a)获取文件大小fs.sizeOf(ss.txt);
                  b)计算切片大小computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M
                  c)开始切,形成第1个切片:ss.txt—0:128M第2个切片ss.txt—128:256M第3个切片ss.txt—256M:300M(每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1倍就划分一块切片)当然类中方法也会判断,如果是压缩文件之类的,是不会切片的。报异常。
                  d)将切片信息写到一个切片规划文件中
                  f)整个切片的核心过程在getSplit()方法中完成。(是FileInputFormat类中的方法)
           (4)提交切片规划文件到yarn上,yarn上的MrAppMaster就可以根据切片规划文件计算开启maptask个数。
     
    3.通过分析源码,在FileInputFormat中,计算切片大小的逻辑:Math.max(minSize, Math.min(maxSize, blockSize));  切片主要由这几个值来运算决定
      FileInputFormat中默认的切片机制:
    (1)简单地按照文件的内容长度进行切片
    (2)切片大小,默认等于block大小
    (3)切片时不考虑数据集整体,而是逐个针对每一个文件单独切片
    比如待处理数据有两个文件:
    file1.txt    320M
    file2.txt    10M
    经过FileInputFormat的切片机制运算后,形成的切片信息如下: 
    file1.txt.split1--  0~128
    file1.txt.split2--  128~256
    file1.txt.split3--  256~320
    file2.txt.split1--  0~10M
    4)FileInputFormat切片大小的参数配置
    (1)通过分析源码,在FileInputFormat中,计算切片大小的逻辑:Math.max(minSize, Math.min(maxSize, blockSize)); 
    切片主要由这几个值来运算决定
    mapreduce.input.fileinputformat.split.minsize=1默认值为1
    mapreduce.input.fileinputformat.split.maxsize= Long.MAXValue默认值Long.MAXValue
    因此,默认情况下,切片大小=blocksize。
    maxsize(切片最大值):参数如果调得比blocksize小,则会让切片变小,而且就等于配置的这个参数的值。
    minsize(切片最小值):参数调的比blockSize大,则可以让切片变得比blocksize还大。
    5)获取切片信息API :FileSplit是inputSplit的子类。
    //根据文件类型获取切片信息
    FileSplit inputSplit = (FileSplit) context.getInputSplit();
    //获取切片的文件名称
    String name = inputSplit.getPath().getName();//获取的是被切片文件名:
    选择并发数的影响因素:
    1- 运算节点的硬件配置
    2- 运算任务的类型:CPU密集型还是IO密集型
             3- 运算任务的数据量
    map并行度的经验之谈
       1.如果硬件配置为2*12core + 64G,恰当的map并行度是大约每个节点20-100个map,最好每个map的执行时间至少一分钟。
       2.如果job的每个map或者 reduce task的运行时间都只有30-40秒钟,那么就减少该job的map或者reduce数,每一个task(map|reduce)的setup和加入到调度器中进行调度,这个中间的过程可能都要花费几秒钟,所以如果每个task都非常快就跑完了,就会在task的开始和结束的时候浪费太多的时间。
    配置task的JVM重用可以改善该问题:1
    mapred.job.reuse.jvm.num.tasks默认是1,表示一个JVM上最多可以顺序执行的task
    数目(属于同一个Job)是1。也就是说一个task启一个JVM   
    注释:JVM重用技术不是指同一Job的两个或两个以上的task可以同时运行于同一JVM上,而是排队按顺序执行
      3.如果input的文件非常的大,比如1TB,可以考虑将hdfs上的每个block size设大,比如设成256MB或者512MB
    2.ReduceTask并行度的决定
    reducetask的并行度同样影响整个job的执行并发度和执行效率,但与maptask的并发数由切片数决定不同,Reducetask数量的决定是可以直接手动设置,默认值为1.
    //默认值是1,手动设置为4
    job.setNumReduceTasks(4);
    如果数据分布不均匀,就有可能在reduce阶段产生数据倾斜
    注意: reducetask数量并不是任意设置,还要考虑业务逻辑需求,有些情况下,需要计算全局汇总结果,就只能有1个reducetask
    尽量不要运行太多的reduce task。对大多数job来说,最好rduce的个数最多和集群中的reduce持平,或者比集群的 reduce slots小。这个对于小集群而言,尤其重要。
    1)job提交流程源码详解
    waitForCompletion()
    submit();
    // 1建立连接
           connect();
                  // 1)创建提交job的代理
                  new Cluster(getConfiguration());
                         // (1)判断是本地yarn还是远程
                         initialize(jobTrackAddr, conf);
           // 2 提交job
    submitter.submitJobInternal(Job.this, cluster)
           // 1)创建给集群提交数据的Stag路径
           Path jobStagingArea = JobSubmissionFiles.getStagingDir(cluster, conf);
           // 2)获取jobid ,并创建job路径
           JobID jobId = submitClient.getNewJobID();
           // 3)拷贝jar包到集群
    copyAndConfigureFiles(job, submitJobDir);
           rUploader.uploadFiles(job, jobSubmitDir);
    // 4)计算切片,生成切片规划文件
    writeSplits(job, submitJobDir);
           maps = writeNewSplits(job, jobSubmitDir);
                  input.getSplits(job);
    // 5)向Stag路径写xml配置文件
    writeConf(conf, submitJobFile);
           conf.writeXml(out);
    // 6)提交job,返回提交状态
    status = submitClient.submitJob(jobId, submitJobDir.toString(), job.getCredentials());
  • 相关阅读:
    HDU3336 Count the string(kmp
    HDU2087 剪花布条(字符串...半暴力写的?
    HDU4763 Theme Section(kmp
    HDU1251 统计难题(字典树|map
    HDU1305 Immediate Decodability (字典树
    priority_queue member function
    HDU
    洛谷 P3370 【模板】字符串哈希 (set||map||哈希||字典树(mle)
    mysql (master/slave)复制原理及配置
    mysql备份小记
  • 原文地址:https://www.cnblogs.com/dflmg/p/9552307.html
Copyright © 2020-2023  润新知