一、概述
HDFS(Hadoop Distributed File System)是Hadoop提供的一套用于进行分布式存储的文件系统
HDFS是Doug仿照Google的GFS来实现的
二、细节归纳
一、基本概述
1.HDFS本身是一个典型的MS结构的框架:主节点NameNode,从节点DataNode -通过slaves文件来指定从节点,HDFS的主节点通过hdfs-site.xml来指定
2.HDFS对会上传的数据进行切分,切成数据块(Block)来存储到不同的DataNode上
3.HDFS会对存储的数据来进行备份,每一个备份称之为是一个副本(replication/replicas)。副本策略默认为3
4.NameNode需要记录元数据(metadata),元数据就类似于账本
5.HDFS仿照Linux设计了一套文件系统,允许将文件存储在不同的虚拟路径下,根路径是/
二、Block
1.Block是HDFS中数据存储的基本形式,即任意一个文件存储到HDFS上之后都是以Block形式来存储
2.在Hadoop2.0中,Block的大小默认是128M,可以通过dfs.blocksize来进行调节,单位是字节,放在hdfs-site.xml中
3.如果一个文件不足一个Block的默认大小,那么这个文件放到HDFS上之后,文件本身是多大就占多大的地方,对应的Block也是文件的实际大小
4.HDFS会为每一个Block分配一个唯一的Block ID
5.HDFS会为每一个Block分配一个递增的Generation Stamp
6.HDFS切块的意义
- 能够存储超大文件
- 能够快速的备份
三、NameNode
1.NameNode是HDFS中的主节点,默认情况下HDFS中,NameNode只有一个
2.作用:记录元数据,管理DataNode
3.元数据是描述数据的数据,可以理解为是一个账本
4.HDFS中的元数据主要包含
- 文件的上传路径
- 上传用户
- 文件的权限
- 文件大小
- Block大小
- 文件和BlockID的映射关系
- Block的Genertion Stamp
- BlockID和DataNode的映射关系
- 副本数量
5.NameNode将元数据维系在内存以及磁盘中
- 维系在内存中的目的是为了读写快
- 维系在磁盘中的目的是为了持久化
6.元数据在磁盘上的存储路径由属性hadoop.tmp.dir来决定,这个属性是放在core-site.xml中。如果不指定,那么默认是放在/tmp下
7.和元数据相关的文件
- edits:操作文件。记录NameNode接收的每一个写请求
- fsimage:元映像文件。记录元数据的,但是注意,这个文件中的元数据和内存中的元数据并不是同步的
8.当NameNode收到写请求的时候,会先将写请求这个命令本身记录到edits_inprogress文件中,如果记录成功更新内存中的元数据。如果内存中的元数据更新成功,就会给客户端返回ack信号。注意,此时fsimage文件中的元数据并没有修改
9.当达到指定条件之后,edits_inprogress文件会产生滚动,滚动生成一个新的edits_inprogress,原来的edits_inprogress会自动重命名为edits文件,HDFS会将edits文件中记录的命令取出来一一执行更新到fsimage文件中,修改fsimage中的元数据
10.edits_inprogress文件的滚动条件
- 空间:当edits_inprogress文件达到指定大小(默认是64M,可以通过fs.checkpoint.size来调节,单位是字节,放在core-site.xml中)的时候,会产生滚动
- 时间:当距离上一次滚动的时间达到指定间隔(默认是1H,可以通过fs.checkpoint.period来调节,单位是s)的时候,edits_inprogress文件也会产生滚动。注意,Hadoop第一次启动的时候,启动1min之后edits_inprogress自动的滚动一次
- 重启:当NameNode重启的时候,edits_inprogress文件也会自动滚动
- 强制:利用hadoop dfsadmin -rollEdits来强制滚动
11.NameNode通过心跳机制来管理DataNode - DataNode定时向NameNode发送心跳信息
12.DataNode每隔3s(通过dfs.heartbeat.interval来调节,单位是s,放在hdfs-site.xml中)向NameNode发送一次心跳,当NameNode超过10min没有收到DataNode的心跳,那么就认为这个DataNode已经lost(丢失),这个时候NameNode会将这个DataNode上的数据备份到其他节点上来保证副本数量
13.心跳信息
a.DataNode的状态(预服役、服役、预退役)
b.clusterid:集群编号
- 在对NameNode进行格式化(hadoop namenode -format)的时候,会自动计算产生一个clusterid
- 每次格式化都会重新计算产生一个新的clusterid
- 当HDFS集群启动的时候,NameNode在接收第一次心跳的时候,会将clusterid在心跳响应中分发给每一个DataNode
- 当DataNode收到clusterid之后就不会再次接收新的clusterid了
- DataNode每一次通信都会携带clusterid,当NameNode收到DataNode的信息的时候会先校验clusterid是否一致。如果不一致则直接拒绝;如果一致才会处理这个DataNode的请求
- 多次格式化,会导致NameNode或者DataNode启动不了
c.DataNode存储的Block信息