HDFS--基本原理和基础组件
基础架构
HDFS(Hadoop Distributed File System)是 Apache Hadoop 项目的一个子项目,是一个分布式的文件存储系统,使用多台计算机存储文件,由hdfs统一管理,提供统一的访问接口,对于客户端来讲就像访问普通文件系统一样。
HDFS中的文件以Block块的形式存储在HDFS文件系统中,Block是hdfs定义的处理单位,目的为:
一个文件有可能大于集群中任意一个磁盘,引入块(Block)机制可以将文件拆成几块,分开存储,而且也有利于文件的冗余备份。
每一个文件都会指定文件的副本数量,Hdfs默认一个文件是三个副本,而且三个副本会存储在不同的机架,和server上。
Hdfs文件的 block 块大小默认是128M, block 块的大小和副本数量可以通过 hdfs-site.xml 当中的配置文件进行指定:
<!-- 块大小,单位为字节 --> <property>
<name>dfs.block.size</name>
<value>134217728</value> </property>
<!-- 副本数量,默认3个副本 -->
<property>
<name>dfs.replication</name>
<value>3</value> </property>
当文件大于配置的块大小时会被拆分,如200M的文件会被拆分为两个块,一个128M另一个72M。
当文件小于配置的块大小时不会拆分,如100M的文件不会拆分,只有一个100M的块。
这里有一点需要注意,如果是两个1M的文件,会占用两个128M的块吗,这个问题作者曾经查过很多资料,都说会占用两个block,尽管还有很多剩余空间,而且从hdfs的管理界面查看似乎也是占用两个Block,但是根据实际使用的经验,曾经做过一个项目,最开始的时候由于经验不足,生成了海量的小文件,如果真是一个1M的文件就占用一个block,可以确定我们的系统早就撑爆N次了,所以可以确认,一个block不可能只存一个很小的文件,但是究竟hdfs是怎么管理的,目前还无法确认,有兴趣的读者可以自己研究以下,但是hdfs是一个大数据的存储系统,确实不适合存储小文件,小文件太多不利于文件的存储,计算(以后讲到spark的计算时会解释这一点),会增加nameNode的压力。所以如果产生了很多小文件,需要根据Block的大小将小文件合并,然后再存储。
HDFS 基础架构由四个角色组成:HDFS Client、NameNode、DataNode 和 SecondaryNameNode。
HDFS Client
HDFS客户端提交读写命令到HDFS,它负责:
文件切分:文件上传 HDFS的时候,Client 将文件切分成Block,然后进行存储。
与NameNode 交互:获取文件真实的位置信息。
与DataNode 交互:读取或写入数据。
Client 提供一些命令来管理 和访问HDFS。
NameNode
NameNode 是HDFS的Master节点,它负责:
管理 HDFS 的名称空间
管理Block元数据
管理副本策略
处理客户端读写请求
周期性的接收心跳和块的状态信息报告
DataNode
DataNode 是HDFS的Slave节点,它负责:
存储数据
Block的读写操作
周期性向NameNode汇报心跳信息,Block信息,缓存信息
SecondaryNameNode
SecondaryNameNode不是NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务,而是作为一个辅助者分担NameNode的工作量。在介绍的HDFS的高可用中会介绍真正的NameNode热备机制。
nameNode中保存了元数据,元数据会被加载到内存中,但是也必须持久化到磁盘中,nameNode中有两类文件用来持久化元数据,
- fsimage文件,以fsimage_为前缀,是元数据的整体快照
- edits文件,又称为edit log,以edits_为前缀,顺序存储元数据的增量修改,类似于mysql的binlog
我们需要定期的将edits文件合并到fsimage文件,合并过程叫checkpoint,为了减轻nameNode的压力,checkpoint的工作由secondaryNameNode(SNN)负责,
- 首先nameNode生成新的edit log(_inprogress后缀的文件),之前写的edit log即为待合并状态
- 将带合并的fsimage和edit log复制到SNN, SNN 合并生成fsimage.checkpoint文件。
- 将合并好的文件传回nameNode
如果nameNode启用了HA, 那么SNN的工作就由standby状态的nameNode承担。
合并机制主要由core-site.xml文件中的两个参数来管理:
<!-- 多久记录一次 HDFS 镜像, 默认 1小时 -->
<property>