随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。
HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS的使用场景:适合一次写入,多次读出的场景。一个文件经过创建、写入和关闭之后就不需要改变。
对于HDFS架构来说,一个HDFS基本集群的节点主要包括:NameNode、DataNode、SecondaryNameNode。
NameNode是名称节点,Master;DataNode是数据节点;SecondaryNameNode是辅助名称节点;Client是客户端。各部分的详细功能:
Client:主要负责切分文件,与各节点进行交互。切分文件是把文件分割成数据块(Block)。数据块默认大小是128MB,每个数据块有多个副本存储在不同的机器上,副本数可在文件生成时指定(默认有3个副本)。交互包括与NameNode和DataNode进行交互,Client从NameNode获取文件的元数据,从DataNode读取数据并向DataNode写入数据。元数据是描述数据属性的数据。数据属性包括存储的位置、格式、权限、大小、历史版本等。
NameNode:是HDFS架构中的主节点,管理节点(Master)。HDFS架构中只有一个NameNode。NameNode用于存储元数据以及处理客户端(client)发出的请求。元数据不是具体的文件内容,它包含3类重要信息。第1类是文件和目录自身的属性信息,如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等;第2类是文件内容存储的相关信息,如文件分块情况、副本个数、每个副本所在的DataNode信息等;第3类是HDFS中所有DataNode的信息,用于管理DataNode。
在NameNode中存放元数据的文件是fsimage(文件系统镜像)文件。在系统运行期间,所有对元数据的操作均保存在内存中,并被持久化到另一个文件edits(编辑日志文件)中。当NameNode启动时,fsimage文件将被加载至内存,再对内存里的数据执行edits文件中所记录的操作,以确保内存所保留的数据处于最新的状态。
主要负责:
DataNode是HDFS架构中的从节点(Slave)。是真正存储数据的地方,在DataNode中,文件以数据块的形式进行存储。数据文件在上传至HDFS时将根据系统默认的文件块大小被划分成一个个数据块,Hadoop3.x中一个数据块的大小为128MB,如果存储一个大小为129MB的文件,那么文件将被分为两个数据块进行存储。再将每个数据快存储至不同的或相同的DataNode中,并且备份副本,一般默认备份3个副本,NameNode负责记录文件的分块信息,确保在读取该文件时可以找到并整合所有该文件的数据块。
主要负责:
SecondaryNameNode:定期与NameNode通信,主要用来进行镜像备份,对NameNode中的edits文件与fsimage文件进行定期合并。镜像文件是指备份fsimage文件。
fsimage和edits:fsimage(镜像文件)和edits(日志文件)是NameNode中两个很重要的文件。fsimage是元数据镜像文件,内容是NameNode启动时对整个文件系统的快照(备份)。edits元数据操作日志,内容是每次保存fsimage之后至下次保存fsimage之前进行的所有HDFS操作。
随着HDFS操作的次数越来越多,edits文件也会越来越多,所占存储空间越来越大。如果NameNode出现故障,NameNode重启时,会先把fsimage文件加载到内存中,然后合并edits文件,edits文件占空间大会导致NameNode重启很耗时。对于实际操作来说,这是一个比较麻烦的问题。SecondaryNameNode对NameNode中的edits文件与fsimage文件进行定期合并,很好解决了这个问题,这也是HDFS高容错特点的一个表现。
合并edits文件和fsimage文件,SecondaryNameNode每隔1小时执行1次,可能会出现数据丢失问题。目前大部分企业采用Hadoop的HA(High Available,高可用)模式下备用的NameNode,对NameNode中的edits文件与fsimage文件进行实时合并。
合并过程如下:
通常大型Hadoop集群会分布在很多机架上。在这种情况下,不同节点之间的通信希望尽量在同一个机架之内及进行,而不是跨机架;为了提高容错能力,NameNode会尽可能把数据块的副本放到多个机架上。在综合考虑这两点的基础上,Hadoop设计了机架感知(rack-aware)功能。
在Hadoop里,以类似于一种文件目录结构的方式来表示节点。例如,H1的parent是R1,R1的parent是D1,则H1的RackID=/D1/R1/H1。其他节同理可以获取得到机架的ID。有了这些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/R2/H4) = 4 用以IDC下的不同DataNode
distance(/D1/R1/H1, /D2/R3/H7) = 6 不同IDC下的DataNode
HDFS副本的方式策略称为机架感知策略。以默认的3个副本为例,具体策略如下:
这种策略减少了机架间的数据传输,从而提高了写操作的效率。机架故障的可能性远小于节点故障的可能性,这个策略保证了数据的可靠性。但是,它不会减少读取数据时使用的总网络带宽,因为一个块仅放置在两个唯一的机架中,而不是三个。使用此策略,块的副本不会在机架上均匀分布。两个副本位于一个机架的不同节点上,其余副本位于其他机架之一的节点上。此策略在不影响数据可靠性或读取性能的情况下提高了写入性能。
为了降低整体的带宽消耗和读取延时,HDFS会让程序尽量读取离它最近的副本。如果读取程序的同一个机架上有一个副本,那么就读取这个副本;如果一个Hadoop集群跨越多个数据中心,那么优先读取本地数据中心的副本。
每个DataNode周期性地向NameNode发送心跳信号,网络割裂会导致DataNode与NameNode失去联系。NameNode通过心跳信号的缺失来检测这一情况,并将这些近期不再发送心跳信号的DataNode标志为宕机,不会再将新的I/O请求发送给它。DataNode的宕机可能引发一些数据块的副本数低于指定值,NameNode不断检测这些需要复制的数据块,一旦发现某数据块的副本数低于设定副本数就启动复制操纵。再某个DataNode节点失效,某个副本遭到损坏,DataNode上的硬盘出现错误,或者文件的副本系数增大时,数据块就需要重新复制。
HDFS中所有的元数据都保存在NameNode上,名称节点维护着两个重要文件:fsimage和edits。如果这两个文件发生损坏,整个HDFS将失效。Hadoop采用两种机制来确保名称节点的安全。第一种,把名称节点上的元数据信息同步存储在其他文件系统(比如网络文件系统NFS)中,当名称节点失效时,可以到有元数据的文件系统中获取元数据信息。后面提到的HDFS HA就是采用共享存储系统来存储edits的。当一个NameNode出现故障时,HDFS自动切换到备用NameNode上,元信息则从共享存储系统中获取。第二种,运行一个SecondaryNameNode,当名称节点宕机后,可以把SecondaryNameNode作为一种补救措施,利用SecondaryNameNode中的元数据信息进行系统恢复,但是这种方法仍然会有部分数据丢失。通常情况下会把这两种方法结合使用。
在HDFS架构使用过程中,可能会出现数据损坏的情况。这种情况发生时HDFS的处理步骤如下: