1、HDFS的优缺点:
优点:
① 高容错 ② 可扩展 ③ 适合大文件存储 ④ 可构建在廉价的机器上缺点:
① 高延迟 ② 文件不能修改 ③ 不适合小文件存储2、HDFS架构(类似于文件系统):
①基本组件:
1)NameNode:
① 管理元数据( 镜像文件:HDFS文件系统的目录,和文件的序列编号,副本数)
② 处理客户端的读写请求 ③ 监测datanode状态2)SecondaryNameNode:
① 合并fsimage和fsedits然后再发给namenode
3)DataNode :
① 负责存储client发来的数据块block
② 执行数据块的读写操作 ③ 心跳机制(每隔三秒发送报告自身状态,10分钟未发送,则认为节点死亡。每隔1个小时发送块状态)4)Client:
① 对数据进行切块
② 对HDFS 进行数据的读写操作
②HDFS写入流程:
1 ) 客户端通过FileSystem向Namenode请求上传文件,namenode首先会检查上传的文件在元数据中是否存在,如果不存在才可以上传
2)客户端对上传的文件进行切块,并且把第一个块请求上传到datanode的哪些节点上 3)NameNode返回上传到datanode节点的信息(例如3台),比如分别为datanode1 datanode2 ,datanode3 4)客户端通过FSDataOutPutStream 请求向datanode1上上传数据,datanode1接收到数据之后,datanode1开始调用datanode2, 之后datenode2在调用datanode3 建立通信管道 5)Datanode1 ,datanode2,datanode3 逐级回应客户端可以上传 6)客户端开始向datanode1上 上传数据(第一个block块)是以packet为单位,datanode1 接收到第一个packet 放到缓存中,并且保存到磁盘,同时datanode1传给datanode2、datanode3 7)当第一个block上传完成之后,继续上传第二个block块 依次类推注:①当上传数据,建立连接通道时候,发现其中一台机器挂掉,那么client会重新向namenode申请,namenode重新分配三个节点
②当正在上传数据时候,如果dn3挂掉,那么系统会不处理,因为其他的两个节点已经上传成功。
当dn3在继续启动的时候,在进行块报告时,会删除自身的错误块,然后namenode发现只有两个 副本,会分配其他的机器进行副本复制。 ③当正在上传数据时候,如果dn1挂掉或者客户端挂掉,那么会在edit上面记录本次操作失败, 在进行块报告时,会删除错误块(由于edit有错误记录)
③HDFS读取流程:
1)客户端通过FileSystem向NameNode请求下载文件,NameNode查询元数据,把查询之后的结果返回给客户端(文件块所在的datanode的位置)
2)挑选一台datanode开始读取(就近原则) 3)DataNode开始传输数据给客户端(从磁盘里面读取FSDataInutStrem,以packet 为单位) 4)客户端以packet为单位接收,现在本地缓存。然后把数据写入到目标文件,后面的block追加到本地文件中,最终合并成需要的文件
④NameNode运行机制:
注:① 镜像文件:HDFS文件系统的目录,和文件的序列编号,副本数
② 编辑日志:客户端更新文件系统中操作的路径,以及命令③ 当用户进行增删文件操作时候,先写进编辑日志,然后写进去了之后,在进行实质的上传、删除操作。
④ 为什么写进编辑日志:因为每次服务器开启的时候,会从镜像文件中加载出目录,如果之前进行增删操作,不写进去的话, 那么服务器重启会显示不出来更改之后的东西。 所以说如果服务器一直开启的话,编辑日志、镜像文件是没啥用的。第一阶段: namenode启动
1) 第一次启动namenode需要格式化,创建fsimsage,与 edits文件。如果不是第一次启动,需要加载编辑日志文件(edits,用户操作)与镜像文件(fsimage,目录树)到内存中
2) 客户端对namenode的元数据进行增删的请求,首先会找到编辑日志文件,记录操作日志,当日志记录成功之后 3) Namenode对内存中的元数据进行修改第二阶段: SecondaryNamenode工作机制
1)SecondaryNamenode询问NameNode是否需要checkpoint,得到namenode是否检查的结果
2)Namenode滚动正在写编辑日志文件 3)将滚动之前的日志文件,与镜像文件拷贝到SecondaryNamenode 4)SecondaryNamenode加载日志文件和镜像文件到内存中继续合并 5)生成新的镜像文件fsimage.checkpoint 6)把新的fsimage.checkpoint镜像文件拷贝会namenode 7)进行数据校验 8)把新的fsimage.checkpoint 改名为fsimage注:检查点时间间隔可以自行设置hdfs-site.xml
⑤DataNode运行机制:注:时间都是设置的hdfs-site.xml
①校验和 : 传输文件时,会在开头或者结尾设置一个字符串,两边进行验证。1 ) 数据是以数据块的方式在datanode上存储,在datanode上存储的数据其中包括两个文件一个数据本身,另一个是数据的长度,时间戳 校验和
2) DataNode启动之后,会向NameNode进行注册,注册成功之后,会周期性的向NameNode汇报块的信息(默认1个小时) 3) 每3秒与NameNode进行心跳的发送,如果10分钟nameNode没有接收到Datanode的心跳则认为该节点死亡, 从其他DN中备份一份该DN上的所有block,1个小时汇报一次块信息。 ⑥机架感知: 第一个副本放在和Client相同机架的Node里(如果Client不在集群范围,第一个Node是随机选取不太满或者不太忙的Node) 第二个副本放在与第一个Node不同的机架中的Node 第三个副本放在与第二个Node所在机架里不同的Node. ⑦例题: 如果集群中的NN设置块大小为128,副本为3,其他一个DN设置块大小为256,副本为2,那使用这台机器上传文件, 块大小和副本数为多少? 答:块大小是256,副本为2,这些都是由客户端决定的。3、Yarn架构(类似于操作系统):
①基本组件:
1)Resourcemanager :
①处理客户端的请求,对各个nodemanger上资源进行统一管理和调度。
②负责资源分配,而资源分配和调度的基本单位是Container,其中封装了集群资源(CPU、内存、磁盘等),每个任务只能在Container中运行,并且只使用Container中的资源;2)NodeManager :
①负责集群中单个节点中的资源管理,并且处理来自resourcemanager的命令,负责上报节点的状态。
②负责启动Application所需的Container,并监控资源的使用情况汇报给ResourceManager3)ApplicationMaster : 主要负责向ResourceManager申请Application的资源,获取Container并跟踪这些Container的运行状态和执行进度,
执行完后通知ResourceManager注销ApplicationMaster,ApplicationMaster也是运行在Container中;4)Container : 对任务运行环境的抽象,封装了 CPU 内存 等资源,MR任务在container中运行
②Yarn工作机制:
1)客户端向yarn提交job
2)YarnRunner向ResouceManage申请该job所需资源 3)ResouceManage将应用程序的资源路径返回给YarnRunner 4)client将程序需要运行的资源(jar、切片信息、配置文件等)上传到该路径上(HDFS)5)资源上传完毕,client通知RM 并且申请运行Application Master,此申请在RM的队列中(先进先出)
6)RM把队列中的任务,将其分配给剩余资源多的节点(心跳机制,每个NodeManager每3秒向ResourceManager发送自身资源状态)。7)NodeManager,接受到任务,创建容器Container并在此上启动Application Master
8) Application Master从HDFS上拷贝资源到本地,并且向RM进行注册,对此任务进行跟踪 9)Application Master向RM申请运行maptask资源10)RM给需要运行maptask的NodeManager发送指令,nodemannager启动container,
11)Application Master在相应的nodeManager节点上启动mapTask(分区 排序),并将产生的输出保存在自己的节点上12)Application Master 等待所有maptask任务运行完毕之后,向RM申请资源运行Reduce
13)Reduce Task 任务向Maptask中拉取相应分区的数据14)程序运行完毕之后MR 会想RM 申请注销自己的任务
4、负载均衡
Hadoop的HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,例如:当集群内新增、删除节点,或者某个节点机器内硬盘存储达到饱和值。
当数据不平衡时,Map任务可能会分配到没有存储数据的机器,这将导致网络带宽的消耗,也无法很好的进行本地计算。 当HDFS负载不均衡时,需要对HDFS进行数据的负载均衡调整,即对各节点机器上数据的存储分布进行调整。从而,让数据均匀的分布在各个DataNode上,均衡IO性能,防止热点的发生。 进行数据的负载均衡调整,必须要满足如下原则:1、数据平衡不能导致数据块减少,数据块备份丢失
2、管理员可以中止数据平衡进程 3、数据均衡过程,不能影响namenode的正常工作在Hadoop中,包含一个start-balancer.sh脚本,通过运行这个工具,启动HDFS数据均衡服务。该工具可以做到热插拔,即无须重启计算机和 Hadoop 服务。
$Hadoop_home/bin/start-balancer.sh //里面有一些参数,可以自己配置一下
HDFS副本摆放策略
第一副本:放置在上传文件的DataNode上;如果是集群外提交,则随机挑选一台磁盘不太慢、CPU不太忙的节点上; 第二副本:放置在于第一个副本不同的机架的节点上; 第三副本:与第二个副本相同机架的不同节点上;5、MapReduce
1 MapReduce优缺点
优点: 1易于编程 :很方便的编写一个分布式程序,只需要继承两个类就可以完成(Mapper类与reduce类)2 良好的扩展性: 当计算的资源不足的时候,可以非常简单的增加nodemanager节点
3 容错性高: 数据的容错性(HDFS上存在备份) ,计算的容错性(当进行计算的时候,当前节点出现了问题,则可以把当前的计算任务转移到另外一个节点上)
缺点:
1 不适合做实时分析处理(豪秒级返回结果)
2 MapReduce的结果数据都是在磁盘上,效率不高
2、数据结构 1、基本数据类型 Java hadoopbyte ByteWritable
int IntWritable long LongWritablefloat FloatWritable
double DoubleWritableString Text
boolean BooleanWritable Null NullWritable Map MapWritable Array ArrayWritable 2、自定义数据类型注:自定义类型必须实现writable,并使属性可序列化
public class FlowBean implements Writable{
public long upFlow;
@Override
public void readFields(DataInput in) throws IOException { this.upFlow=in.readLong(); }@Override
public void write(DataOutput out) throws IOException { out.writeLong(upFlow); } }3、mapreduce shuffle过程(从map输出到reduce输入)
1) MapTask收集map输出的(k,v)对交给环形缓冲区 // map上下文写入就是写到环形缓冲区
2) 环形缓冲区默认为100MB(大小可调整),达到80%的时候,溢出文件到本地磁盘上,每次溢写一个文件。//每一次写缓冲达到溢写临界值(80%)时,都会形成一个新的溢写文件
3) 在文件的溢写过程中,会根据key对(k,v)进行分区和排序(发生在缓冲区)
4) 分区的规则:是按照key.hashcode%reduceNumber 的结果进行分区(默认分区是reduce个数) //同一key,hashcode相同,会分到同一分区文件中 5) 排序的规则:默认key值升序排序。6) 将溢写的文件全部合并成一个大文件
7) ReduceTask 会把来自不同maptask的分区文件(每个maptask只有一个文件)加载到本地缓存中,同一分区编号进行归并排序并且分组
8) 每个reduce合并成一个文件之后,shuffle过程就结束了
注:第七步、第八步经常忘掉,重要注:每个文件一个map,那么100文件就是map,假如分了四个区(默认分区是reduce个数) ,会产生100个文件,每个文件有顺序、有区域的包含此maptask的四个区的所有文件
ReduceTask默认在4台机器上进行合并,将同一区的进行归并排序,所以会产生4个结果文件 并且对相同的key进行分组计算,也就是reduce中的迭代。注:缓冲区是缓存满了80%之后,map结果向20%中写(k,v),80%的缓冲区内容会进行分区排序,写到本地,进行缓存。
意思是满80%就写,但是输入口不会关闭。注:Combine出现在两个地方:写缓冲区溢写过程中、溢写文件合并过程中。
注:三次排序,缓冲区中,溢写文件合并中,reduce拉取文件合并
注:调整缓冲区的大小,就和spark差不多了,溢写的次数就比较少了,maptask更加高效
注:每个maptask都有一个环形缓冲区,每次溢写一个文件(如果分区数为2,那么这个文件有两个区的内容,前半段是A区的内容,后半段是B区的内容)。
如果溢写过程中缓冲区已满,则进入堵塞状态。 4、mapreduce 执行过程(全过程) 1) 读取HDFS中的文件。每一行解析成一个<k,v>。每一个键值对调用一次map函数。eg : <0,hello you> <10,hello me>
2) 覆盖map(),接收前面产生的<k,v>,进行处理,转换为新的<k,v>输出。
eg : <hello,1> <you,1> <hello,1> <me,1>
3) shuffle过程
6、Hadoop优化
1、推测执行:
原因:因为程序bug,负载不均衡或者资源分布不均,造成同一个job的多个task运行速度不一致,有的task运行速度明显慢于其他task。
解决:为该任务重新启动的一个,备份任务,与原来的任务一致,这两个任务同时运行,哪个任务先执行完毕,则以哪个任务为准。
前提:
1) 每个task只能存在一个备份任务 2) 当前的job 必须完成task任务的5%不适用:
1)任务出现了严重数据倾斜 2)特殊的任务,reduce 把结果输出到数据库中缺点:以空间换时间,当需要备份任务过多,只会更加拖累进程。当发生严重数据倾斜时,备份只会是火上浇油。
2、MR优化:
1)数据的倾斜:
①自定义分区 : 比如北京人数多,巴中人口少,可以把北京的人分为两个区,把巴中、达州的人合并为一个区。 ②自定义combiner层 : 通过maptask之后的结合,会一定程度上减少reduce的负载。 2 )小文件过多:①自定义输入 : 在进行maptask之前,将多个文件合并为大文件。(减少Map)
3)大量不可分割的数据块
①Map阶段 : 尽量减少溢写次数,可以通过调整环形缓冲区的大小来解决
注:缓冲区是缓存满了80%之后,map结果向20%中写(k,v),80%的缓冲区内容会进行分区排序,写到本地,进行缓存。意思是满80%就写,但是输入口不会关闭。