MapReduce底层及注意事项

一、mapreduce框架原理
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019012319493659.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg3MDY5OQ==,size_16,color_FFFFFF,t_701、 mapreduce按照task分,分为maptask和reducetask
2、 mapreduce按流程划分分为inputformat,map,shuffle,reducer,outputformat
二、shuffle流程
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190123195009422.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzg3MDY5OQ==,size_16,color_FFFFFF,t_701、 map()将<k,v>写入环形缓冲区,并且,在写入环形缓冲区之前,这个<k,v>已经知道了它在哪个分区,但是在环形缓冲区中,<k,v>之间不排序,也不分区,这个已知的分区,相当于<k,v>中的一个标签。
注:这个分区是通过(key.hashcode()&Interger.max_value)%numReducerTask取得的,所以相同key,在同一个分区下。
2、 数据刚进入环形缓冲区时后,环形缓冲区数据流程为:
在这里插入图片描述
缓冲区参数:默认100M,数据达到80%后进行反向写数据。
实际工作中参数,缓冲区500M或者是1G都有可能,数据达到90%进行反向。
3、 溢出后,每一次溢出都溢出一个小文件。
如果自定义了Combiner类,那么在溢出后,这些数据进行合并。即将
<a,1><a,1><a,1><b,1><b,1><c,1>这样的数据变成<a,3><b,2><c,1>这种。
4、溢写出小文件,小文件达到一定的数量后,(注:无论中间有没有Combiner过程),都将这些小文件进行归并排序。
5、进行归并排序之后,各个分区中的数据也会出现3的情况,所以,也可以进行数据合并。
注意:如果自定义了Combiner类,那么3,5都要进行Combiner操作。Combiner操作不能影响正常的逻辑,并且,输入输出前后的kv格式是相同的。
6、1-5是一个分片中的数据,最后合成了一个文件。几个分片中的数据,根据分区不同,一起分往不同的reducetask。
7、这些数据,先放在reducetask的内存中,如果内存满了,就会将部分的数据放在磁盘中,然后将磁盘和内存中的数据进行归并排序。
8、归并排序之后,再进行分组,和reduce方法的实现。(如下图)
在这里插入图片描述

三、mapreduce序列化和反序列化底层
mapreduce中所有东西都是序列化的,什么时候用什么时候反序列化成一个对象,并且,序列化成一个对象的地址是相同的,也就是,无论序列化几次,每次都指向同一个地址。举例:如果用一个List去封装每次序列化的对象,List底层是一个数组,数组中的数据指向的是数据的地址,这样,因为序列化的地址不变,就会导致,list中所有数据都是相同的,是最后一次序列化的数据。
在这里插入图片描述
序列化补充:
(1)为什么要序列化?
一般来说,“活的”对象只存在内存里,关机断电就没有了。并且,“活的”对象只能由本地的进程使用,不能被发送到网络上的另一台计算机。然而序列化可以存储“活的”对象,可以将“活的对象发送到远程计算机。
理解:内存的对象只能本地使用,其他计算机没办法使用,要想传到其他计算机,就必须进行序列化,序列化可以存储这些内存中的对象,发送给其他计算机。
(2)什么是序列化?
序列化就是把内存中的对象,转化成字节序列(或者其他数据传输协议)以便于存储磁盘(持久化)和网路传输。
反序列化就是将字节序列(或者其他数据传输协议)或者是磁盘的持久化数据,转化成内存中的对象。
(3)理解:mapreduce程序序列化过程:
A: map 端读取一个文件。获取文件内容,是将磁盘中的持久化数据转化为内存中的对象。用的是反序列化。
B: map 端将数据进行处理。得到的想要的数据后,将内存中的对象转化成字节序列,用于网络传输,传到reducer 。用的是序列化。
C: reducer 端接收数据,将接收到的字节序列转换为内存对象。用的是反序列化。
D:reducer 端将内存对象进行处理后,再转化为字节序列,存储到磁盘中。用的是序列化。
(4)理解:什么时候用序列化,什么时候用反序列化?
当你想把内存中的数据,也就是你已经处理好的数据,进行传输到别的计算机或者是持久化到磁盘时,这个时候用到了序列化。
当你想把磁盘中的数据或者别的计算机传过来的数据传到自己的内存时,用的是反序列化。
总之,要想跨计算机传输,或者要想持久化数据,就必须将数据转换成字节序列(或者其他数据传输协议),也就是必须序列化。要想把接收到的字节序列传到自己的内存中处理,就是反序列化。流程:传输序列化字节序列。接收反序列化内存对象
hadoop序列化只序列化字段/数据,比如name,连方法/类信息都不序列化。所以hadoop用自己的序列化,不用java的,显得很重。
四、其他
1、 为什么切片大小默认等于块大小?
(1)情景一:切片大小小于快大小。
条件:切片大小100M,块大小128M
这样,一个文件存在hdfs的DataNode中一块是128M,但是一个datanode的maptask只能处理100M的数据,那么就需要将剩余没有处理的28M数据放到下一个datanode中进行处理,剩下的以此类推,这样就产生了网络IO,而hdfs最关键的注意点就是减少IO传输,无论是网络IO,还是磁盘IO。
(2)情景二:切片大下大于快大小
条件:切片1G,快大小128M
这种情况下,一个maptask处理不过来。
2、 Inputforamat只要注意这两点就可以了
(1) 切片
(2) 切片往kv值的转变
Inputformat的类是FileInputFormat这个抽象类
实现类都是实现这个抽象类。
默认的实现类:TextInputFormat,切片规则为默认切片,切片转化为kv的类为LineRecordReader。
自定义Inputformat:继承FileInputFormat,重写RecordReader方法。
在这里插入图片描述
3、 异常
写方法的人抛异常,用方法的人处理异常
4、 为什么计算分区数的公式是

中间为什么会和Interger.MAX按位与?
因为Integer.MAX二进制是0111 1111 1111 1111,
如果key.hashCode()是0111 0111 1111 1111,则按位与就是0111 0111 1111 1111
如果key.hashCode()是1111 0111 1111 1111,则按位与还是0111 0111 1111 1111
从上看出,是为了把符号位转换成0,也就是去符号位。
知识点:hashCode()默认也是16位
5、 分区号必须从0开始,逐一累加,不能跳:0,1,2,3,不能0,1,3,因为即使跳了,中间还是会有那个跳过的分区,只不过这个跳过的分区中没有数据而已。
6、 三次Combiner,(两次Combiner,一次Reducer)
每次Combiner都是将分区中数据相同key进行汇总。
Combiner也是一个reducer,那么Combiner中有没有实现分组GroupingComparator?
没有,分组GrooupingComparator只在reducer中使用。
7、 Combiner两个原则:不改变输入输出,不改变逻辑
8、 分组:在reducer中,自定义分组规则,取数据时,默认一个分组一个分组的取,按顺序取。
默认分组规则:是按照自定义bean类中的比较规则分组,如果自定义了分组类,就按照分组类分组。
分组规则:分组规则的粒度比排序规则的粒度大。例如:排序规则是按照id,和价格。分组是用id。
分组的作用:比如要取相同id中价格最高的信息。可以先将这个类用定义到key,然后自定义排序规则,根据id,和价格双重排序,之后,在reducer中按照id进行分组,然后取分组中的第一个就可以了。
9、 分区和分组没有关系:分区发生在map中,分组发生在reducer中
10、 Mr中所有的东西都是以序列化存在的,什么时候用对象,什么时候反序列化成对象。节省IO
11、 分组和reduce方法读数据是同时进行的,不是先分组,再读数据。
12、 mapjoin:小表放在hdfs中每有一个map,就将这个小表复制过来一次。
13、 没有reduce就没有shuffle,因为·shuffle是map到reduce的中间过程。
五、HDFS笔记
1、 hdfs2.x新特性:yarn+HA
2、 为什么hdfs不支持修改?因为底层是java,用的是java的数据流,数据流没办法回头。同样不支持并发,流只能一个一个运行。
3、 粒度:就是单位。Hdfs存储的最小单位(粒度)不是以文件为单位,是以文件快进行存储。
4、 Client负责文件切分。
5、 如果大于128M,一块数据太大,就会导致快处理时间过长。工业生产中基本为256M,512M,因为他们的磁盘速度快。
6、 du :diskusage;df:diskfilesystem;getmerge:合并下载;命令行加 – 标准输入,一次输入很多行;setrep:设置副本数;ls:ListStatuses,文件,文件夹。Lf:LiistFile:可以递归,只有文件。
7、 在这里插入图片描述
文件夹没有副本,说明文件夹不存在于DN,只存在于NN
8、 为什么是串行通道?因为IO
Hdfs的问题考虑:(1)NN存储(2)IO
9、 每次启动hdfs时,都要先加载fsimage,再加载edits,之后再执行一次checkpoint。
10、 yum inatall -y lrzsz :传递linux与Windows之间数据
sz 文件名
11、 fsimage中每一个文件,文件夹的数据信息都在Inodesection的inode中,但是没有目录结构,也没有副本在哪个DataNode上的信息。Inodedri描述的是目录结构。、
12、 DN不止存数据快,还存数据块的元数据。
13、 退役:白名单比黑名单更加严格,黑名单是在自己存在的数据备份到其他机器中,再退役。白名单是直接干掉不在当中的服务器。
一般白名单是防止两套服务器窜的,黑名单用于退役。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值