大数据学习第9天:
Yarn分布式集群环境部署
client发出请求到resourceManager,resourceManager启动Appication master为任务分配相关的资源,分配完成后返回信息到resource Manager,再由resourceManager将任务分发到不同的NodeManager。NodeManager启动Container执行需要的MapReduce工作。
下面根据yarn的工作流程对yarn的工作机制进行解读。首先,client向ResourceManager发出任务请求。Resource Manager指定一个NodeManager启动其ApplicationMaster。ApplicationMaster将计算任务反馈给Resource
Manager。ApplicationMaster将任务分割分发到不同的NodeManager。NodeManager启动Task执行work。
yarn具有双层调度策略,ResourceManager将资源分配给ApplicationMaster,ApplicationMaster再将资源分配给NodeManager。而且,yarn具有预留的调度策略。资源不够时,会为Task预留资源,知道积累充足。
yarn具有较好的容错机制。当任务失败,ResourceManager将失败任务告诉ApplicationMaster。由ApplicationMaster处理失败任务。ApplicationMaster会保存已经执行的Task,重启不会重新执行。
yarn支持多类型资源调度,其基于DRF算法实现(论文:“Dominant Resource Fairness: Fair Allocation of Multiple Resource Types”)。而且,其支持多种资源调度器FIFO、Fair Scheduler以及Capacity Scheduler 。最后,yarn支持多租户资源调度器包括支持资源按比例分配、层级队列划分方式以及支持资源抢占 。
yarn支持内存和CPU两种资源隔离。内存是一种“决定生死”的资源。CPU是一种“影响快慢”的资源。其中,内存隔离包括基于线程监控的方案和基于Cgroups的方案。而CPU隔离包括默认不对CPU资源进行隔离和基于Cgroups的方案。
yarn支持的调度语义包括请求某个特定节点/机架上的特定资源量、将某些节点加入(或移除)黑名单,不再为自己分配这些节点上的资 源以及请求归还某些资源。不支持的语义包括请求任意节点/机架上的特定资源量、请求一组或几组符合某种特质的资源、超细粒度资源以及动态调整Container资源 。
•集群内运行MR程序
–hadoop jar
•分析过程:
–准备CLASSPATH环境
–运行Jar包中类的main方法:激活Client
NN-1 | NN-2 | DN | ZK | ZKFC | JNN | RS | NM | |
---|---|---|---|---|---|---|---|---|
node01 | * | * | * | |||||
node02 | * | * | * | * | * | * | ||
node03 | * | * | * | * | * | |||
node04 | * | * | * | * |
mapred-site.xml
•
• mapreduce.framework.name
• yarn
•
yarn-site.xml
•
• yarn.nodemanager.aux-services
• mapreduce_shuffle
•
•
• yarn.resourcemanager.ha.enabled
• true
•
•
• yarn.resourcemanager.cluster-id
• cluster1
•
•
• yarn.resourcemanager.ha.rm-ids
• rm1,rm2
•
•
• yarn.resourcemanager.hostname.rm1
• node03
•
•
• yarn.resourcemanager.hostname.rm2
• node04
•
•
• yarn.resourcemanager.zk-address
• node02:2181,node03:2181,node04:2181
•
了解:mapreduce分布式计算机框架核心部分源码
•思路:
•1,客户端干了什么
–Job
•2,框架干了什么
–MapTask
–ReduceTask
•3,MR语义:
–相同的key作为一组调用一次reduce
–相同是由排序保证的
–具体的比较方法实现产生不同的排序标准
•计算向数据移动(理想状态)
–数据本地化读取
•客户端作业提交源码分析
•hdfsdfs-get /tmp/hadoop-yarn/staging/root/.staging/job_1498934454157_0003/*./
•Configuration
–default.xml
–site.xml
•MRJobConfig
–观察默认值
•JobContextImpl
–JobConf conf
–观察默认值
•Job
–set*()
–waitForCompletion(true)
•waitForCompletion
–submit();
–monitorAndPrintJob();
–return isSuccessful();
•submit
–connect();
–submitter.submitJobInternal(Job.this, cluster);
•submitJobInternal
–checkSpecs(job);
–copyAndConfigureFiles(job, submitJobDir);
–int maps = writeSplits(job, submitJobDir);
–status = submitClient.submitJob( jobId, submitJobDir.toString(), job.getCredentials());
mapper阶段流程小结
总结起来,mapper阶段的工作流程如下:
1.先把输入的文件,按照一定的标准和方法做切分(InputSplit)。这个切分的过程很关键,因为MR的核心思想就是将一个巨大的任务切分成多个小任务分发给不同节点计算,每一个输入片对应的就是一个mapper。如果切分没有做好,后面的工作自然就无从谈起。后续有时间再专门阐述一下切分相关的具体细节。
2.对切分完的输入按照一定的规则解析成(k,v)对。
3.调用Mapper类中的map()方法,对第二步解析出来的(k,v)对进行操作。这也是我们需要实现真正逻辑的地方。每调用一次map()方法,就会输出0个或1个或多个(k,v)对。
4.对第三步输出的(k,v)对进行partition 。partition是基于k进行的,这样就保证相同的k落在同一个分区之中。
5.对第四步产生的(k,v)对排序。首先是按k排序,如果k相同,则按v排序。如果后续还有combiner阶段,则继续进行combiner;如果没有,则直接将数据输出到磁盘。
6.combiner阶段。其实跟reduce的实现逻辑是一样的。比如在wordcount中,reducer类都不用实现,直接在run()方法中用job.setReducerClass(IntSumReducer.class)设置即可
掌握WordCount案例,并且mapreduce详细流程图说说WordCount的执行过程
一、Mapper代码
public class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
/**
- 一个Block对应一个Mapper
- 一个行出发一次Mapper中的map
- Key:map的输入,是当前处理的行在文件中的偏移量
- value:map的输入,是当前行的内容
- context:环境对象,用来输出数据
*/
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text,
Text, LongWritable>.Context context)throws IOException, InterruptedException {
String line = value.toString();
String [] words = line.split(" ");
for(String word : words){
context.write(new Text(word), new LongWritable(1));
}
}
}
二、Reducer代码:
public class WCReducer extends Reducer<Text,LongWritable,Text,LongWritable> {
/**
- Reducer进行数据的合并处理
- key:reduce的输入,是map的输出
- values:reduce的输入,是map输出中键相同的值的集合
- context:环境对象,可以输出数据
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values,
Reducer<Text, LongWritable, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
String word = key.toString();
long count = 0;
for(LongWritable l : values){
count += l.get();
}
context.write(new Text(word), new LongWritable(count));
}
}
-
- 三、Dirver代码:
public class WCDriver { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf ); job.setJarByClass(WCDriver.class); job.setMapperClass(WCMapper.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(LongWritable.class); FileInputFormat.setInputPaths(job, new Path("/wc/words.txt")); job.setReducerClass(WCReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); FileOutputFormat.setOutputPath(job, new Path("/wc/result01")); job.waitForCompletion(true); } }
四、发布
然后将项目打成jar包,上传到虚拟机上,执行:hadoop -jar xxx.jar 执行
五、Combiner合并
合并的目的是减少Reduce端 迭代的次数
combiner是实现Mapper端进行key的归并,combiner具有类似本地的reduce功能。如果不用combiner,那么所有的结果都是reduce完成,效率会很低。使用combiner先做合并,然后发往reduce。
六、Shuffle三、Dirver代码:
四、发布
然后将项目打成jar包,上传到虚拟机上,执行:hadoop -jar xxx.jar 执行
五、Combiner合并
合并的目的是减少Reduce端 迭代的次数
combiner是实现Mapper端进行key的归并,combiner具有类似本地的reduce功能。如果不用combiner,那么所有的结果都是reduce完成,效率会很低。使用combiner先做合并,然后发往reduce。
六、Shuffle
系统将map输出作为reduce输入称为shuffle。shuffle是MapReduce的“心脏”,是奇迹发生的地方。
知识点1:Spill的分区和Reduce分区有关吗?有关
知识点2:一定会产生spill文件吗?不一定,假设一开始的输出就没有达到溢写阈值,就不会发生Spill过程,也就不会发生Merge过程
知识点3:假设输出数据是90MB,当写满80MB时,发生一次Spill,剩下的10MB会通过flush()刷到文件里,确保数据不丢失。
知识点4:溢写缓冲区大小默认是100MB,但是可以更改。阈值也可以改
知识点5:一个Map任务对应一个溢写缓冲区。
知识点6:一个Map任务结束后,会生成一个结果文件(前提是发生了Spill和Merge过程)
知识点7:不能单纯的根据128MB切片来决定Spill的文件数量,要根据Mapper里的代码来决定
知识点8:Hadoop的一个调优策略是调大溢写缓冲区大小,从而减少Spill溢写次数,介绍磁盘I/O次数,从而提供性能。
知识点9:什么时候开始Merge过程?一个Map任务完成时,即不再输出k,v对的时候,开始Merge。