block(数据块)
建立在磁盘之上,数据块的大小是磁盘块的整数倍,HDFS中的文件被划分为多个分块(chunk),一个小于一个块大小的文件不会占用整个块的空间。
1.x的HDFS块大小默认为64MB,2.x的HDFS块大小默认为128MB。- 查看HDFS中文件的块信息
hadoop fsck / -files -blocks
使用数据块概念的优点
- 一个文件可以分成多个块,所有的数据块可以存储在多个磁盘上(分布式)。
- 简化系统设计(分布式系统的故障种类比较多,简化是所有系统的目标),可以提供数据的容错能力和提高数据的可用性:每个数据块会同时复制到几个独立的机器上。
namenode
namenode管理文件系统的命名空间,维护文件系统树及整个树内所有文件和目录。这些信息以命名空间镜像文件(fsimage)和编辑日志文件(editslog)的形式存放在磁盘中。
namenode记录每个文件中各个块所在的数据结点信息(元数据)(保存在内存中),这些信息会在系统启动时由数据结点重建。
文件的元数据:复本的级别,修改时间,访问时间,访问许可,块大小,组成文件的块。
目录的元数据:修改时间,访问许可,配额元数据。namenode格式化后的目录结构
${dfs.name.dir}/ current/ VERSION edits fsimage fstime VERSION: Java属性文件,包含了正在运行的HDFS的版本信息。内容为: namespaceID=**** cTime=0 storageType=NAME_NODE layoutVersion=-18 layoutVersion:描述HDFS持久性数据结构(布局)的版本,与Hadoop的版本号无关,当布局的版本变更时,版本号会递减,此时HDFS也需要升级。 namespaceID:文件系统的唯一标识符,在首次格式化时设置。任何datanode在注册到namenode之前都不知道namespaceID的存在。 cTime:标记namenode存储系统的创建时间,刚格式化时为0,当HDFS升级时会保存为当时的时间戳。
namenode的高可用性
NFS(网络文件系统)
在多个文件系统中保存namenode中的元数据,将数据写入本地磁盘的同时,写入一个远程的网络文件系统中(NFS).
因为NFS也会存在单点故障问题,所以实际中很少会使用到。
2.辅助namenode方式
使用一个单独的机器定期通过editlog合并fsimage,防止editlog文件过大;类似于namenode的副本,但是数据的状态滞后于namenode结点,当namenode发生故障时,难免会丢失部分数据。
辅助namenode创建检查点的步骤
1:请求主namenode停止使用editslog,暂时将新的写操作记录到一个新的editslog.
2:辅助namenode从主namenode中以HTTP GET的方式获取fsimage和editslog文件
3:辅助namenode将fsimage载入内存,并逐一执行editslog文件的操作,创建新的fsimage文件。
4:辅助namenode将新的fsimage文件以HTTP POST的方式发送给主namenode.
5:主namenode将接收到的新的fsimage替换旧的fsimage文件,用步骤1中创建的editslog替换旧的editslog,同时更新目录结构中的fstime文件来记录检查点执行的时间。这样主namenode会拥有最新的fsimage和一个较小的editslog文件。
创建检查点的触发条件为1:fs.checkpoint.period属性(单位为秒);2:fs.checkpoint.size属性(editslog文件的大小,单位为字节,系统每5分钟会检查一下editslog的文件大小).创建检查点的另一方法
管理员在namenode处于安全模式下,使用hadoop dfsadmin -saveNamespace命令创建。
使用辅助namenode恢复数据的方式
1:将辅助namenode的目录复制到主namenode中
2:使用-importCheckpoint启动namenode守护进程,将辅助namenode作为新的主namenode。
datanode
datanode负责存储检索数据块,并定期向namenode发送它们所存储的数据块的列表。
datanode目录结构
${dfs.data.dir}/current/ VERSION /blk_<id_1> /blk_<id_1>.meta /blk_<id_2> /blk_<id_2>.meta ... /subdir0 #子目录 /subdir1 VERSION文件与namenode中的文件非常相似,其中namespaceID,cTime,layoutVersion与namenode中的相同,是在首次访问namenode的时候从namenode的VERSION中获取的。StorageID为每个datanode的唯一标识,StorageType为DATA_NODE
目录中的文件格式有两种,一种存储原始数据的块文件,另一种是该块的元数据文件(保存该块文件的校验和)。
数据块文件数量
dfs.datanode.numblocks属性(默认64)限定每个目录下能保存的文件的上限。当文件数量达到这个上限时,就创建一个子目录(subdir{序号}).
数据流
数据读取
获取文件的步骤为:
1:客户端调用namenode节点获取文件起始块的datanode地址。
2:连接到datanode并获取数据优势
namenode告诉客户端每个块的最佳datanode地址,并让客户端直接连接到该datanode,数据流分散到集群中的datanode中,可适应大量的并发客户端。另外由于块的元数据都存储在namenode的内存中,因此客户端从namenode中获取datanode地址时非常快速。
数据写入
创建文件步骤:
1:客户端调用namenode在命名空间中创建一个空文件。
2:客户端将文件分割成一个个数据包,并写入本地的”数据队列”和”确认队列”并传输给datanode,当hdfs中配置的文件副本数大于1个时,datanode会将数据包传输给第二个datanode结点,依次传递。当客户端收到datanode的确认信息后才会删除”确认队列”中的数据包。
3:文件的所有数据包都写完后,通知namenode。