我们依然是先过一遍官方文档:
引言
Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。
硬件错误
硬件错误是常态而不是异常。HDFS可能由成百上千的服务器所构成,每个服务器上存储着文件系统的部分数据。我们面对的现实是构成系统的组件数目是巨大的,而且任一组件都有可能失效,这意味着总是有一部分HDFS的组件是不工作的。因此错误检测和快速、自动的恢复是HDFS最核心的架构目标。
流式数据访问
运行在HDFS上的应用和普通的应用不同,需要流式访问它们的数据集。HDFS的设计中更多的考虑到了数据批处理,而不是用户交互处理。比之数据访问的低延迟问题,更关键的在于数据访问的高吞吐量。POSIX标准设置的很多硬性约束对HDFS应用系统不是必需的。为了提高数据的吞吐量,在一些关键方面对POSIX的语义做了一些修改。
大规模数据集
运行在HDFS上的应用具有很大的数据集。HDFS上的一个典型文件大小一般都在G字节至T字节。因此,HDFS被调节以支持大文件存储。它应该能提供整体上高的数据传输带宽,能在一个集群里扩展到数百个节点。一个单一的HDFS实例应该能支撑数以千万计的文件。
简单的一致性模型
HDFS应用需要一个“一次写入多次读取”的文件访问模型。一个文件经过创建、写入和关闭之后就不需要改变。这一假设简化了数据一致性问题,并且使高吞吐量的数据访问成为可能。Map/Reduce应用或者网络爬虫应用都非常适合这个模型。目前还有计划在将来扩充这个模型,使之支持文件的附加写操作。
“移动计算比移动数据更划算”
一个应用请求的计算,离它操作的数据越近就越高效,在数据达到海量级别的时候更是如此。因为这样就能降低网络阻塞的影响,提高系统数据的吞吐量。将计算移动到数据附近,比之将数据移动到应用所在显然更好。HDFS为应用提供了将它们自己移动到数据附近的接口。
异构软硬件平台间的可移植性
HDFS在设计的时候就考虑到平台的可移植性。这种特性方便了HDFS作为大规模数据应用平台的推广。
Namenode 和 Datanode
HDFS采用master/slave架构。一个HDFS集群是由一个Namenode和一定数目的Datanodes组成。Namenode是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的Datanode一般是一个节点一个,负责管理它所在节点上的存储。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Datanode上。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。
官方文档还给出了图片:
我在尝试使用HDFS上传文件的时候,估计跟大家的感觉一样,像是在本地上传到本地的感觉。
而实际上HDFS是将文件分成若干块保存在不同的服务器的节点中,为了降低文件丢失造成的错误,它会为每个小文件复制多个副本(默认为三个),以此来实现多机器上的多用户分享文件和存储空间。
再来解释一下上图,详细讲解一下Namenode与Datanode。
Namenode
是有点类似于Linux的根目录,管理数据块映射、处理客户端的读写请求、配置副本策略、管理HDFS的名称空间。
作用:
- Namenode起一个统领的作用,用户通过namenode来实现对其他数据的访问和操作,类似于root根目录的感觉。
- Namenode内存中储存的是:fsimage(元数据[1]镜像文件) + edits(元数据[1]的操作日志) 【此两个文件也是核心文件】
- Namenode中仅仅存储目录树信息,而关于BLOCK的位置信息则是从各个Datanode上传到Namenode上的。
- Namenode的目录树信息就是物理的存储在fsimage这个文件中的,当Namenode启动的时候会首先读取fsimage这个文件,将目录树信息装载到内存中。
而edits存储的是日志信息,在Namenode启动后所有对目录结构的增加,删除,修改等操作都会记录到edits文件中,并不会同步的记录在fsimage中。
而当Namenode结点关闭的时候,也不会将fsimage与edits文件进行合并,这个合并的过程实际上是发生在Namenode启动的过程中。
也就是说,当Namenode启动的时候,首先装载fsimage文件,然后在应用edits文件,最后还会将最新的目录树信息更新到新的fsimage文件中,然后启用新的edits文件。【这个会在后面实践的时候展示给大家看】
整个流程是没有问题的,但是有个小瑕疵,就是如果Namenode在启动后发生的改变过多,会导致edits文件变得非常大,大得程度与Namenode的更新频率有关系。
那么在下一次Namenode启动的过程中,读取了fsimage文件后,会应用这个无比大的edits文件,导致启动时间变长,并且不可控,可能需要启动几个小时也说不定。
Namenode的edits文件过大的问题,也就是SecondeNamenode要解决的主要问题。
SecondNamenode(副本Namenode)保存着NameNode的部分信息(不是全部信息NameNode宕掉之后恢复数据用),是NameNode的冷备份[2]【在这里顺便科普热备份[3]】,合并fsimage和edits然后再发给namenode,防止edits文件过大,导致Namenode启动时间过长。——》【执行过程:从NameNode上 下载元数据信息(fsimage,edits),然后把二者合并,生成新的fsimage,在本地保存,并将其推送到NameNode,同时重置NameNode的edits. 】
Datanode
是负责存储client发来的数据块block;执行数据块的读写操作。是Namenode的小弟。 DataNode在HDFS中真正存储数据。
首先解释块(block)的概念:
- DataNode在存储数据的时候是按照block为单位读写数据的。block是hdfs读写数据的基本单位。
- 假设文件大小是100GB,从字节位置0开始,每128MB字节划分为一个block,依此类推,可以划分出很多的block。每个block就是128MB大小。
- block本质上是一个 逻辑概念,意味着block里面不会真正的存储数据,只是划分文件的。
- block里也会存副本,副本优点是安全,缺点是占空间
此处上一张大神的图片:
总结特点
特点:
- 存储最高TB级别大的文件
- 采用流式的数据访问方式
- 运行的时候不吃硬件
不适用的场景:
- 低延时的数据访问
- 大量小文件
- 多方读写,需要任意的文件修改
具体的读写过程可以参考:【详细,值得参考,帮助理解】
要是大家还有对HDFS的读写有疑问,还可以参考一下链接:
地址:https://blog.csdn.net/wang_da_king/article/details/81258652
下一期,我们将下载hadoop,来简单体验一下HDFS。