HDFS架构、常用特性。
提示:
HDFS(Hadoop Distributed File System)是一个分布式的文件系统。适合一次写入,多次读出的场景,且不支持文件的修改。具有高容错性,数据自动保存多个副本,某一个副本丢失后,还可以自动恢复。适合数据吞吐量高的程序使用。
HDFS是主从架构,整个集群由一个NameNode组成,在主节点上,管理文件系统命名空间,并处理客户端对文件的访问。DataNodes,在每一个节点上,每个DateNode管理其所在节点的存储。HDFS的文件系统命名空间允许将用户数据存储在这个文件中。在HDFS中,一个文件被切分成一个或多个块存储在一组DataNode里。NameNode操作文件系统命名空间,比如:打开,关闭,重命名文件和目录。还管理DataNodes中文件块的映射。DataNode还负责为来自文件系统客户端的读写请求提供服务。DataNode还负责执行来自NameNode的创建,删除,复制的指令。
1)NameNode:就是Master,他是一个主管,管理者
(1)管理HDFS的命名空间;
(2)配置副本策略
(3)管理数据块(block)映射信息;
(4)处理客户端读写请求
2)DataNode:就是Slave。NameNode下达命令,DataNode执行实际的操作。
(1)存储实际的数据块;
(2)执行数据块的读写操作;
3)Client:就是客户端。
(1)文件切分,文件上传HDFS的时候,Client将文件切分成一个一个的Block,然后进行上传。
(2)与NameNode交互,获取文件的位置信息;
(3)与DataNode交互,读取或写入数据;
(4)Client提供一些命令来管理HDFS,比如NameNode的格式化;
(5)Client可以通过一些命令来访问HDFS,比如HDFS的增删改查操作;
4)Secondary NameNode:并非NameNode的热备。当NameNode挂掉的时候,它并不能马上替换NameNode并提供服务。
(1)辅助NameNode,并分担其工作量,比如定期合并Fsimage和Edits,并推送给NameNode;
(2)在紧急情况下,可辅助恢复NameNode;
HDFS使用的是传统的文件目录,用户或者程序可以在这个目录下创建目录或存储文件。文件系统命名空间的结构和大多数的文件系统类似:可以创建和删除文件,将一个文件从一个目录转移到另一个目录或者重命名这个文件。支持使用用户配额和访问权限,不支持硬链接或者软链接。
HDFS遵循文件系统命名约定,但是保留了一些路径和名称(例如 /.reserved 和 .snapshot),透明加密和快照等功能使用预留出来的路径。
NameNode维护文件系统命名空间。NameNode记录文件系统命名空间和其属性的任何更改。应用程序可以指定存储在HDFS上文件的副本数。
HDFS中每个文件在物理上都作为块来存储,块大小和副本数都是可以配置(dfs.blocksiza)的。默认的块大小是128M.
块的大小不能设置太大或者太小,太小会增加寻址时间,太大的话,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间,导致程序在处理这块数据的时候,会非常慢。HDFS块大小的设置主要取决于磁盘传输的速率。
文件中除了最后一个块以外的其他块大小相等。程序可以指定文件的副本数,在创建文件的时候可以指定,之后还可以修改,HDFS是只能一次写入文件(追加和删除除外),并且在同一时间只能有一个用户来写入。
关于块的复制所有的命令全来自于NameNode。它会监听DataNode的心跳和块信息。心跳证明DtaNode的健康,一个块信息包含一个DataNode上所有的块的信息。
1)副本放置位置
副本放置位置的选择对HDFS的性能和可靠性都至关重要。机架感知和副本放置策略的目的就是提高数据的可靠性,性能,和网络带宽的利用率。
很多Hadoop的一个集群通常分布在不同的机架上。在这种情况下,为了希望不同节点之间的通信能够尽量发生在同一个机架上,而不是跨机架,并且为了提高容错能力,NameNode会尽可能把数据块的副本放到多个机架上面。
综合这两点考虑,Hadoop设计了机架感知功能。
当NameNode通过机架感知确定了每个DataNode所属机架的ID,有一种简单的策略就是每个副本放在不同的机架上,这样可以大大增加可靠性,防止机架发生故障时数据丢失,并且允许在读数据的时候使用多个机架的带宽,。这种策略可以均匀的分布副本,从而平衡组件发生故障的负载,但是这种策略在写入的过程会增加成本,因为写入时需要跨越不同机架。
对于常见的情况,当副本数为3时,HDFS的放置策略为:如果写入程序在一个DataNode上,那么在这个DataNode上放置一个副本,如果写入程序不在一个DataNode上,那么在这个写入程序的同一个机架上随机选择一个DataNode放置一个副本,然后在另一个距离较远的机架上放置第二个副本,最后一个副本放置在与第二个副本相同机架上的不同DataNode上。
这个放置策略可以减少机架间的写入成本,提高写入的性能。由于机架故障的概率低与节点故障的概率,所以此策略不影响数据的可靠性。因为是放在两个机架上,不是三个,所以它不会减少读取数据时的成本。
如果副本数大于3时,则随机确定其余的副本位置,同时还要保证每个机架上面的副本数量少于((副本数-1)/机架数+2).
由于NameNode不允许在同一个DataNode上有同一个块的多个副本,所以,一个块的最大副本数就是DataNode的个数。
2)读取副本选择
为了最大程度上减少副本读取时的成本,和减少延迟,HDFS会选择最接近读取用户的副本。如果副本在读取用户同一个机架上,则使用这个副本
3)安全模式
在启动的时候,NameNode会进入安全状态。在安全状态时,不会进行数据块的复制。NameNode接受来自DataNode的心跳和块信息。一个块信息包含一个DataNode上的所有数据块的列表。每一个块都有指定的最小副本数,当NameNode检查过这个块的存在的副本数大于等于这个块的最小副本数,这个块就被定义为安全的。当NameNode经过检查,超过一定百分比数量的数据块时安全的,那么在30秒后,NameNode退出安全模式。如果还有数据块的副本小于规定的副本数,那么NameNode开始复制这个副本到其他DataNode。
HDFS的命名空间存储在NameNode节点上。NameNode使用EditLog这个事务日志去持续记录文件系统元数据的每一条变化。例如:创建新的文件就会导致NameNode将记录插入到EditLog.同样的,更改文件的副本个数,也会导致将新的记录插入到EditLog中。NameNode在本地文件系统中使用一个文件存储EditLog.整个系统命名空间(包括块的映射信息,文件系统的配置)都被存储在一个叫FSImage的文件中。FSImage一样是一个文件存储在NameNode的本地空间。
NameNode在内存中会保存全部的文件系统命名空间和文件块映射。当NameNode启动或检查点被触发时,它会在磁盘上读取FSImage和EditLog,然后把EditLog合并到内存中的FSImage,再把内存中的FSImage刷新到磁盘上的FSImage。然后截断旧的EditLog,因为它的事务已经刷新到了FSImage中。这个过程被称为checkpoint。checkpoint这个过程的目的:通过拍元数据快照然后保存到FSImage的方式来确保HDFS元数据的数据一致。
虽然直接读取FSImage是有效果的,但是我们直接把进行修改的操作追加到FSImage却是不行的,所以我们需要的是每条操作之后,修改FSImage,当我们把每条操作追加写到EditLog中,然后再用EditLog去修改FSImage。Chackpoint这个操作,可以由两个条件去触发,1.在给定的时间间隔触发(dfs.namenode.checkpoint.period),2.可以在积累了一定的操作次数之后触发(dfs.namenode.checkpoint.txns)。当这两个参数都配置了之后,有一个达到条件就会触发Chackpoint。
DataNode将HDFS中的文件存储在本地文件系统中,它对文件的内容不清楚。它将每个文件块单独的存放在本地文件系统中。DataNode并不会将所有的文件存放在同一个目录下,相反它确定每个目录下的文件存放的最佳数量后,适当的创建子目录。在同一个目录下,并不适合创建所有的本地文件,因为本地文件系统对一个目录下有大量的文件并不是很友好。当DataNode启动的时候,他会扫描他的本地文件系统,生成一个与本地文件系统对应的HDFS数据块列表,并把这个列表发送到NameNode。这个列表就是块报告(Blockreport)。
HDFS所有的通讯协议都是TCP/IP协议。客户端在NameNode机器上建立一个可配置的TCP端口的连接。DataNode与NameNode的通讯使用DataNode协议。远程通讯(RPC),NameNode不启动RPC,他只响应DataNode或客户端发出的RPC请求。
在出现故障的情况下,HDFS也需要可靠的保存数据。常见的三种故障类型是:NameNode故障,DataNode故障,和网络延迟。
1)数据磁盘故障,心跳和重复复制副本
每一个DataNode都会定期的想NameNode发送心跳,但是网络延迟会导致一个DataNode与NameNode失联。NameNode决定DataNode是否存在的条件就是DataNode发送的心跳信息。NameNode将没有按照规定时间内发送心跳信息的节点标记为dead,并且不再像这个节点发送命令。被标记为dead的DataNode不再被HDFS使用,不提供任何数据。DataNode的死亡可能会导致某些数据块的最低副本数不够,NameNode会追踪哪些需要复制的副本,并在必要的时候开始复制。重复复制副本可能存在以下几点原因:
1.DataNode不可用。
2.副本损坏。
3.DataNode上的磁盘故障。
4.文件的设置的副本数增加。
对于DataNode的超时时间,尽量长一点(默认是十分钟),为了避免由于DataNode的不稳定导致疯狂复制副本。
由于某些需求,需要响应的快速,也可以设置更短的超时时间,将DataNode标记为陈旧的节点,通过配置,来避免读取或写入陈旧节点。
2)再次平衡集群
HDFS架构支持多种数据再平衡方案。如果DataNode上的空闲空间低于某个阈值,HDFS可能会自动将数据从一个DataNode移动到另一个DataNode。如果突然对特定文件有很高的需求,HDFS可能会动态创建额外的副本,并重新平衡集群中的其他数据。但是这些类型的数据再平衡方案还没有实现。
3)数据完整性
由于存储设备故障,网络故障或软件漏洞,可能会导致从DataNode读取的数据损坏。所以需要HDFS的客户端对HDFS的文件内容进行校验。当一个客户端创建一个文件时,会对此文件的每一个文件块生成一个校验码,并作为隐藏文件单独存放在这个文件块相同的文件命名空间位置中。当客户端检索文件时,会验证每个从DataNode收到的数据块的校验码是否与相关联的检查文件中的校验码的值相同。如果不同,会在另一个具有该数据块的DtaNode上面重新下载,并继续校验。
4)元数据文件故障
FSImage和EditLog是HDFS的核心数据结构,这些文件的损坏可能会导致HDFS直接不可用。所以,可以将NameNode配置为支持维护FSImage和EditLog的多个副本。FSImage或EditLog的任何更新都会同步更新到FSImage和EditLog副本上。虽然这样做同步更新会降低NameNode的文件命名空间的效率,但是这种损失是可以接受的,因为HDFS是数据密集性,但不是元数据密集型的。当NameNode重启时,他会选择最新的FSImage和EditLog。
5)快照
快照可以存储某一时间点的数据副本。快照的一种用法是将一个产生故障的HDFS集群回滚到原来已知的一个正确的时间点。实现故障修复。
1)数据块
HDFS的目标是支持大型的数据,与HDFS兼容的软件一般也是处理大型数据的应用程序。这些程序一般是一次写入多次读取,而且还对读取的速率有一定的要求。HDFS支持一次写入多次读取。一个数据块通常被设置成128M大小,这样的效率比较高。因此,HDFS文件被切碎成128M每块,如果条件允许,每块将位于不同的DataNode上。
2)副本复制流程
当客户端写入一个具有三个副本的文件时,NameNode使用一种选择算法检索DataNodes的列表。在这个列表里面选出复制该文件的DataNode,当客户端开始向第一个DataNode里面写数据时,这个DataNode以文件块的形式接收,然后将每个块写入本地磁盘并同时将该块传输给下一个DataNode。第二个DataNode开始一次接收数据的每个块,并将该块写入到本地磁盘,然后传输该块到第三个DataNode。最后,第三个DataNode将数据写入到本地磁盘。DataNode可以从管道的前一个DataNode接收数据,同时将数据转发到管道中的下一个DataNode。所以,数据是从一个DataNode管道到下一个DataNode。
bin/hadoop dfs -mkdir /test1
bin/hadoop fs -rm -R /test1
bin/hadoop dfs -cat /test/myfile.txt
bin/hdfs dfsadmin -report
3)在web页面访问hdfs,3.0以后的版本的端口号为9870
可以在web页面进行操作
1)文件的删除与转换成垃圾文件
HDFS中,默认开启垃圾回收模式,通过shell命令删除的文件并不会立马就被删除,而是移动到了垃圾目录(/user/(username)/.Tresh)。当文件还保留在垃圾目录时,是可以快速恢复的。
如果是刚刚删除的文件,将会移动到(/user/(username)/.Tresh/Current/)下,HDFS在一定的时间间隔内会在(/user/(username)/.Tresh/)下创建CheckPoint,当旧的CheckPoint过期的时候,就会将这个文件删除。
当垃圾文件的生命周期结束的时候,NameNode会把它的名称从HDFS的命名空间中删除,同时也会删除它的块文件,但是在删除文件的时候,删除成功到真正系统释放出它的空间,会有一段明显的延迟。
删除一个文件的时候
bin/hadoop fs -rm -R /test
下方会出现信息,显示此文件或文件夹被移动到了 /user/hdfs/.Trash/Current/test
查看这个文件夹
sudo -u hdfs bin/hadoop fs -ls /user/hdfs/.Trash/Current/
bin/hadoop fs -rm -R -skipTrash /test
此时直接显示Deleted /test 并没有进行移动。
2)减少副本数
当减少一个文件的副本数的时候,NameNode会选择可以删除的多余的副本,在下一个心跳的时候,将这个信息传递给相应的DataNode。然后DataNode删除相应的数据块,这样相应的空闲空间就会出现在集群中。在删除命令执行到集群出现相应的空闲空间,这之间还是会有明显的延迟时间。
3)设置副本数
现在看到myfile.txt是三个副本,分别存在cdh1,cdh2,cdh3
使用 -setrep 命令来设置副本数
bin/hadoop fs -setrep 2 /test1/myfile.txt
现在可以看到是变成了两个副本,存放在在cdh2,cdh1上。
如果设置副本数超过DataNode节点的数量,则实际副本数以DataNode节点的数量为准,后期如果新服役节点的话,会自动增加副本。