这篇文章是学习MR时候整理的不全也不深,等我再看看。。。。
可以看出这里面并没有这个方法,所以推断出来,是他的父类的方法
hdfs默认的是textinput,之后如果我们想通过别的及自己设置即可
选maxsize跟blocksize中最小的,如果我们不改变maxsize(默认值是long的最大值),则取到他俩中最小的是blocksize
然后再跟minsize比较选一个大的,如果不改变minsize的默认值(很小很小的数),则取到的他俩最大的就是blocksize
这里我们可以得出如果我们不设置一些信息的话,默认blocksize就跟splitsize是一样,也就是默认那个1:1的关系
所以,我们可以想到,
如果要使切片的大小大于blocksize,我们就把minsize加到很大
如果要使切片的大小小于blocksize,我们就把maxsize减小
也就是说片拿到了块的信息
(当然这里我么看到的是默认,1:1,否则也有别的可能)
切片存在的原因:为了满足一些需求,我们不能直接用块的大小,所以切片就可以根据我们开发需求设置他大小,那他是怎么设置出来的呢?他的底层有一个minsize还有一个maxsize两个标志性变量再加一个blocksize通过之前的那个算法比较得出来的,默认情况下1:1,通过minsize,maxsize我们可以调整切片大小跟块大小的比列对应,计算出splitsize后,我们通过切片的大小去对接blocklocation(列表信息)位置的索引,通过索引拿到位置信息与偏移量对接,添加到splits列表信息里面
提交作业
inputformat(底层默认是textinput)类通过job加载了配置信息进来(包含输入信息输出信息),主要是做了一件这样的事情:对切片进行了计算,这个计算得出来切片列表的一系列信息:文件、偏移量、大小、位置,并且我们知道了其切片大小是怎么计算出来的(minsize、masize设置的标志变量/blocksize(通过文件知道)之间的比较判定切片的大小是什么)然后对应切片和切片列表,通过切片和切片列表拿出块,然后通过块拿到索引值,通过索引值拿到切片偏移量和块的位置信息联系起来创建了切片的列表信息
切片的列表信息是什么,怎么计算出来的
///MAP///
两个阶段
map的输入:
map的输出:
客户端-hdfs/resourcemanage
一个框架要从架构模型上讲
Hadoop 代码流程(mapreduce组件细节):
客户端设置了要执行的map/reduce的这两个类
客户端提交了任务后(waitforcomletetion),回启动maptask任务,通过上下文拿数据(输入阶段) ,作为输入,之后,我们进行写操作(输出阶段) (调用map方法(我们重新写的没那个map方法))
Hadoop架构(在运行中牵扯到谁):三大块,客户端数据存储端、数据计算层
客户端先将提交的作业提交到整个集群之上,在运行时会进行一系列的计算,这里主要是切片,这里是配置文件信息(分布式资源),通过这个配置信息,客户端切片,然后把这些数据提交给hdfs,然后hdfs会把这些数据保存下来
第二件事,客户端与计算层进行连接,第一步与nn链接第二步与resourcemanage进行通信,因为他这个时候要真正的去执行这些数据了,yarn去管理(resourcemanage)创建出来一个applicationmaster,会根据情况向resourcemanage申请资源,创建一个containner容器,作为作业执行的一个资源,因为他是短服务,现在被kill掉,然后通过nodemanage来接管任务(map、reduce),当执行到具体的任务的时候,比如说是map:maptask类会创建具体的对象,去执行具体的任务
在初始化之前,我们需要做一些准备工作就是下图
taskContext:定义了上下文
job:里面有conf配置信息
mapper对象是反射(通过job,跟taskContxt)出来的
inputFormat:我们在客户端的时候也讲过(输入文件的格式化类)
split:根据输入进来的切片创建切片对象,客户端吧切片做好了,我们这里通过getSplitDetails获取到切片信息
input:通过NewTrackingRecordReader创建读取器
这里我们看一下NewTrackingRecordReader
这个方法 ctrl+点进去(NewTrackingRecordReader)
所以我们知道real存的是切片上的一些数据,我们回到MapTask类里面继续查看:
通过Mapper里面的context.nextKeyValue()找到WrappedMapper
里面的mapContext.nextKeyValue()
继续找到MapContextImpl里面的reader.nextKeyValue();
,然后找到了MapTask里面的这个nextKeyValue()
也就意味着我们刚刚所说的所有的数据都存在real里面(split的所有信息,一行一行的存在)
这些都是准备的一些阶段,现在我们来看initialize
根据刚刚说的(real是通过三成包装出来的通过 , )
对于分布式的数据我们通过seek(偏移量),就从切片的什么位置开始
这里从第二个片开始(只要不是第一个)那么由于切割可能会
破坏行数据,使得原本是属于同一行(同一条)的数据受到破坏,所以,我们从这些片的第二行开始读,第一行数据交由上一个片来处理
客户端切好偏了,是通过inputformat进来,拿到切片根据他的文件偏移量大小位置
这些信息,根据偏移量那的时候可能由于切割导致的数据的不完整,所以为了补救,他在底层,是从第二个切片开始,每个切片从第二行开始读入,第一行交给上一个切片来处理,
二怎么凶第二行开始呢,这里是通过,new Text(),保存在这个匿名对象里,也就是说保存在堆空间中,上一个切片通过拉取将第一行拉过去计算
看输出啦!!!!!!!!(复杂)
partition使我们可以优化设计的一个点
毕竟根据hash分区并不能解决所有需求,所以有时候我们需要在客户端设置我们自己的
为什么要进行分区呢:
reduce在拉取的时候是根据分区器的
未完待续。。。。。。