目录
基础架构
HDFS Client
NameNode和DataNode
fsimage和edits
SecondaryNameNode
高可用架构
JournalNode
联邦机制
副本机制
机架感知
安全模式
平衡策略
读写原理
读原理
写原理
删除恢复机制
HDFS相关内容:
HDFS(Hadoop Distributed File System)是 Apache Hadoop 项目的一个子项目,Hadoop 非常适于存储大型数据, 其就是使用 HDFS 作为存储系统,而HDFS 使用多台计算机存储文件,并且提供统一的访问接口,像是访问一个普通文件系统一样使用分布式文件系统。作为大数据生态最重要的组件之一,HDFS充当着大数据时代的数据管理者的角色,为各种分布式计算组件提供用于处理的数据存储的能力。
HDFS 基础架构由四个角色组成:HDFS Client、NameNode、DataNode 和 SecondaryNameNode。
HDFS客户端提交读写命令到HDFS,它负责:
NameNode 是HDFS的Master节点,它负责:
DataNode 是HDFS的Slave节点,它负责:
在Hadoop集群当中,NameNode的所有元数据信息都保存在fsimage 与 edits 文件中, 这两个文件记录了所有的数据的元数据信息,当集群重启时NameNode首先会从fsimage和edits文件中将元数据信息加载到内存中,因此NameNode机器对内存的要求相对会比DataNode高很多,元数据信息的保存目录配置在了 hdfs-site.xml 中的这两个参数:dfs.namenode.name.dir,dfs.namenode.edits.dir。
edits
fsimage
由于集群重启时NameNode会重新加载fsimage和edits文件,fsimage文件加载起来很快,但edits文件内记录的都是操作日志,因此edits文件不能无限增长,否则重放日志很慢,会影响到集群启动的速度,因此edits文件和fsimage会定期进行合并。
SecondaryNameNode不是NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务,而是作为一个辅助者分担NameNode的工作量。在后面的内容中介绍的HDFS的高可用中会介绍真正的NameNode热备机制。
上面提到edits文件会根据一定策略和fsimage合并,主要由core-site.xml文件中的两个参数来管理:
fs.checkpoint.period
3600
fs.checkpoint.size
67108864
当edits和fsimage文件合并策略触发时,合并流程如下:
上面我们介绍的都是HDFS的基础架构,从上面的内容中我们也可以看出,NameNode对于HDFS很重要,整个HDFS文件系统的元数据信息都由NameNode来管理,NameNode的可用性直接决定了Hadoop 的可用性,一旦NameNode进程不能工作了,就会影响整个集群的正常使用。因此在Hadoop2.x版本中加入了HDFS HA的特性,在典型的HA集群中,两台独立的机器被配置为NameNode。在工作集群中,NameNode机器中的一个处于Active状态,另一个处于Standby状态。Active NameNode负责群集中的所有客户端 操作,而Standby充当从服务器,Standby机器保持足够的状态以提供快速故障切换。
两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当Active 状态的NameNode的命名空间有任何修改时,会告知大部分的JournalNodes进程。Standby 状态的NameNode有能力读取JNs中的变更信息,并且一直监控edit log的变化,把变化应用于自己的命名空间。Standby 可以确保在集群出错时,命名空间状态已经完全同步了 ,以此达到快速故障切换。
在HA架构下,SecondaryNameNode被JournalNode替代,实现两个NameNode之间的信息同步,由Zookeeper实现两个NameNode之间的高可用,相关的组件如下:
Hadoop3.x版本中的新特性允许2个以上的NameNode节点,该功能能够通过运行更多Standby NameNode来提供更高的容错性,满足一些部署的需求。比如,通过配置3个NameNode和5个JournalNode,集群能够满足允许两个节点故障的容错。
虽然HA模式保证了NameNode的高可用,但HDFS中其实最严重的问题就是小文件过多导致的NameNode维护的元数据信息过多,由此引起的性能下降的问题,因此无论在MapReduce还是Spark程序中都应当尽量避免产生过多小文件。同时HDFS也推出了NameNode的水平扩展方案:联邦机制(Federation)。
HDFS联邦机制表示有多个NameNode,但和HA模式下的多个NameNode的意思不同,在HA模式下的NameNode是主备的概念,而联邦机制中的多NameNode类似分管,表示某个NameNode管理某块命名空间(namespace)内的元数据信息,将本来大量的元数据信息分散在多个NameNode上进行管理,它们之间相互独立不需要互相协助,各自分工,管理自己的区域。
同一个namespace下的block集合被称为Block Pool(存储池),因此在联邦机制下,每个NameNode对应一个Block Pool,对应到DataNode中就是一个个的Block Pool,分别有对应的ID,这时候在DataNode上就不仅仅存储一个Block Pool下的数据了,而是多个,且存储在DataNode的datadir路径里的名为BP-xx.xx的目录。
联邦机制的好处是,多个NameNode共有一个集群里的存储资源,且每个NameNode都可以单独对外提供服务,解决了单个Active NameNode的内存瓶颈问题。但联邦还是没有解决单点故障的问题,假如维护namespace为BP-003的NameNode宕机,则客户端也无法读取DataNode中的/BP-003的数据,因此当集群规模较大的时候,应采用HA+Federation的部署方案,即上图中每个Active NameNode都对应了一个Standby NameNode提升可用性。
HDFS中的文件以Block块的形式存储在HDFS文件系统中,目的为:
在 Hadoop1.x 当中, 文件的 block 块默认大小是 64M,在Hadoop2.x中, 文件的 block 块大小默认是128M, block 块的大小和副本数量可以通过 hdfs-site.xml 当中的配置文件进行指定:
dfs.block.size
134217728
dfs.replication
3
注意:
- 当文件大于配置的块大小时会被拆分,如130M的文件会被拆分为两个块,一个128M另一个2M。
- 当文件小于配置的块大小时不会拆分,如100M的文件不会拆分,只有一个100M的块。
分布式的集群通常包含非常多的机器,由于受到机架槽位和交换机网口的限制,通常大型的分布式集群都会跨好几个机架,由多个机架上的机器共同组成一个分布式集群。机架内的机器之间的网络速度通常都会高于跨机架机器之间的网络速度,并且机架之间机器的网络通信通常受到上层交换机间网络带宽的限制。
Hadoop在设计时考虑到数据的安全与高效,数据文件默认在HDFS上存放三份,存储策略为:
这样设计的好处是:
为了降低整体的带宽消耗和读取延时,HDFS会尽量让程序读取离它最近的节点上的副本,以节约带宽和提升性能。HDFS通过机架感知这一特性实现此功能。
在默认情况下,机架感知没有被启用,所有的机器hadoop都默认在同一个默认的机架下,名为 “/default-rack”,这种情况下,任何一台datanode机器,不管物理上是否属于同一个机架,都会被认为是在同一个机架下,此时,就很容易出现增添机架间网络负载的情况。因为此时hadoop集群的HDFS在选机器的时候,是随机选择的,也就是说,很有可能由于副本的随机分配导致大量的网络传输从而影响性能和集群的服务。
通过修改配置文件core-site.xml 中的参数 topology.script.file.name 开启机架感知,value指定为一个可执行程序,通常为一个脚本(根据入参IP返回该IP地址对应的datanode所在的rack)。
例:网络拓扑如下图:
开启机架感知后,NameNode就可以画出上图所示的datanode网络拓扑图。D1,R1都是交换机,最底层是datanode。则H1的rackid=/D1/R1/H1,H1的parent是R1,R1的parent是D1。有了这些rackid信息就可以计算出任意两台datanode之间的距离。
distance(/D1/R1/H1,/D1/R1/H1)=0 相同的datanode
distance(/D1/R1/H1,/D1/R1/H2)=2 同一rack下的不同datanode
distance(/D1/R1/H1,/D1/R1/H4)=4 同一IDC下的不同datanode
distance(/D1/R1/H1,/D2/R3/H7)=6 不同IDC下的datanode
安全模式是hadoop的一种保护机制,用于保证集群中的数据块的安全性。当集群启动的时候,会首先进入安全模式,当系统处于安全模式时会检查数据块的完整性。
假设我们设置的副本数(即参数dfs.replication)是5,那么在datanode上就应该有5个副本存在,假设只存在3个副本,那么比例就是3/5=0.6。在配置文件hdfs-default.xml中定义了一个最小的副本的副本率0.999,我们的副本率0.6明显小于0.99,因此系统会自动的复制副本到其他的dataNode,使得副本率不小于0.999.如果系统中有8个副本,超过我们设定的5个副本,那么系统也会删除多余的3个副本。
在安全模式下,系统会处于只读状态,NameNode不会处理任何数据块的复制和删除命令。DataNode会向NameNode上传他们数据块的列表,让NameNode得到数据块的位置信息,并对每个文件对应的数据块副本进行统计:
注意:在启动一个刚刚格式化的HDFS时由于没有数据块,所以系统不会进入安全模式。
HDFS安全模式操作命令:
hdfs dfsadmin -safemode get #查看安全模式状态
hdfs dfsadmin -safemode enter #进入安全模式
hdfs dfsadmin -safemode leave #离开安全模式
安全模式相关参数在hdfs-site.xml 文件中配置:
dfs.namenode.safemode.threshold-pct
0.999f
dfs.namenode.safemode.extension
30000
如果 NameNode 长时间处于安全模式,可能是因为 hdfs 的数据损坏过多。使用命令hadoop fsck / 检查 hdfs 文件分布的情况。
在HDFS的DN节点间的数据不平衡情况下,尤其在新增和下架节点、或者人为干预副本数量的时候,会大大的影响数据读取的性能,降低任务的执行速度甚至崩溃,因此HDFS有一个组件叫做Balancer,使用该组件可以保证每个节点的数据均衡分布。
#开始数据平衡:
#用默认的10%的阈值启动balancer
start-balancer.sh
#或指定3%的阈值启动balancer
hdfs dfs balancer -threshold 3
start-balancer.sh -threshold 3
#停止数据平衡:
stop-balancer.sh
hdfs balancer
[-threshold ]
[-policy ]
[-exclude [-f | ]]
[-include [-f | ]]
[-idleiterations ]
-threshold 10 #集群平衡的条件,datanode间磁盘使用率相差阈值,区间选择:0~100。Threshold参数为集群是否处于均衡状态设置了一个目标
-policy datanode #默认为datanode,datanode级别的平衡策略
-exclude -f /tmp/ip1.txt #默认为空,指定该部分ip不参与balance, -f:指定输入为文件
-include -f /tmp/ip2.txt #默认为空,只允许该部分ip参与balance,-f:指定输入为文件
-idleiterations 5 #最大迭代次数,默认为 5
可选的配置参数如下:
#并行移动的block数量,默认5
dfs.datanode.balance.max.concurrent.moves
#Balance工具所占用的带宽,默认1048576(1MB)
dfs.datanode.balance.bandwidthPerSec
#用于执行block移动的线程池大小,默认1000
dfs.balancer.moverThreads
#每次balance进行迭代的过程最大移动数据量,默认10737418240(10GB)
dfs.balancer.max-size-to-move
#获取block的数量,默认2147483648(2GB)
dfs.balancer.getBlocks.size
#用来平衡的最小block大小,默认10485760(10MB)
dfs.balancer.getBlocks.minblock-size
平衡算法根据各Datanode的使用情况,将集群中的节点分为四类:过度闲置、平均值以下、平均值以上、过度使用。
然后根据划分的角色进行配对:
为了保证HDFS数据安全性,数据块移动策略如下:
根据角色配对以及移动策略,Balancer数据均衡流程为:
当触发下面的条件时,Balancer会自动退出:
客户端向HDFS发送读取文件的请求完整流程如下:
NameNode会视情况返回文件的部分或者全部block列表,对于每个block,NameNode 都会返回含有该 block 副本的 DataNode 地址; 这些返回的 DN 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构内距离Client 近的排靠前;心跳机制中超时汇报的 DN 状态为 STALE,这样的排靠后;以此来提升网络传输的效率。
客户端选取排序靠前的 DataNode 来读取 block,如果客户端本身就是DataNode,那么将从本地直接获取数据(短路读取)。
每读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode,然后再从下一个拥有该block 副本的DataNode 继续读。
客户端向HDFS发送上传文件的请求完整流程如下:
当从HDFS中删除某个文件时,这个文件并不会立刻从HDFS中删除,而是将这个文件重命名并转移到回收站 /trash目录,只要这个文件还在/trash目录下,该文件就可以迅速被恢复。回收站的位置在HDFS上的/user/$USER/.Trash/Current/
文件在/trash目录中存放的时间默认为6个小时,当超过这个时间时,NN就会将文件从名称空间中删除;
删除文件会使得该文件相关的数据块被释放;注意:从用户删除文件到HDFS空闲空间的增加之间会有一定时间的延迟;
通过修改hdfs-site.xml文件中下面的配置可以修改回收站过期的时间:
#时间单位是秒
fs.trash.interval
1440
希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!