一、HDFS简介说明
- 管理网络中跨多台计算机存储的文件系统统称为分布式文件系统(distributed fileSystem)。
- 分布式文件系统由于其跨计算机的特性,所以依赖于网络的传输,势必会比普通的本地文件系统更加复杂,比如:如何使得文件系统能够容忍节点的故障并且保证不丢失数据,这就是一个很大的挑战。
二、HDFS基本概念
- HDFS(Hadoop Distributed File System)是hadoop生态系统的一个重要组成部分,是hadoop中的的存储组件,在整个Hadoop中的地位非同一般,是最基础的一部分,因为它涉及到数据存储,MapReduce等计算模型都要依赖于存储在HDFS中的数据。
- HDFS是一个分布式文件系统,以流式数据访问模式存储超大文件,将数据分块存储到一个商业硬件集群内的不同机器上。
1、简单介绍其中涉及到的几个概念:
- 超大文件: 目前的hadoop集群能够存储几百TB甚至PB级的数据;
- 流式数据访问: HDFS的访问模式是:一次写入,多次读取,更加关注的是读取整个数据集的整体时间;
- 商用硬件: HDFS集群的设备不需要多么昂贵和特殊,只要是一些日常使用的普通硬件即可,正因为如此,hdfs节点故障的可能性还是很高的,所以必须要有机制来处理这种单点故障,保证数据的可靠;
- 不支持低时间延迟的数据访问: HDFS关心的是数据的高吞吐量,不适合那些要求低时间延迟数据访问的应用;
- 单用户写入,不支持任意修改: HDFS的数据以读为主,只支持单个写入者,并且写操作总是以添加的形式在文末追加,不支持在任意位置进行修改。
2、HDFS的优缺点
- 优点
- 缺点
注:hdfs上的小文件好像默认是100万个,超过整个集群会挂掉!!!
3、HDFS数据块
- HDFS同样也有数据块的概念,默认一个块(block)的大小为128MB(HDFS的块这么大主要是为了最小化寻址开销),要在HDFS中存储的文件可以划分为多个分块,每个分块可以成为一个独立的存储单元。与本地磁盘不同的是,HDFS中小于一个块大小的文件并不会占据整个HDFS数据块。
- 对HDFS存储进行分块有很多好处:
- 一个文件的大小可以大于网络中任意一个磁盘的容量,文件的块可以利用集群中的任意一个磁盘进行存储。
- 使用抽象的块,而不是整个文件作为存储单元,可以简化存储管理,使得文件的元数据可以单独管理。
- 冗余备份。数据块非常适合用于数据备份,进而可以提供数据容错能力和提高可用性。每个块可以有多个备份(默认为三个),分别保存到相互独立的机器上去,这样就可以保证单点故障不会导致数据丢失。
4、HDFS的重要组成部分:NAMEMODE和DATANODE
- HDFS集群的节点分为两类:NAMEMODE和DATANODE,以管理节点-工作节点的模式运行,即一个NAMEMODE和多个DATANODE,理解这两类节点对理解HDFS工作机制非常重要。
- NAMEMODE作为管理节点: 它负责整个文件系统的命名空间,并且维护着文件系统树和整棵树内所有的文件和目录,这些信息以两个文件的形式(命名空间镜像文件和编辑日志文件)永久存储在NAMEMODE的本地磁盘上。
- NAMEMODE也记录每个文件中各个块所在的数据节点信息,但是不永久存储块的位置信息,因为块的信息可以在系统启动时重新构建。
- DATANODE作为文件系统的工作节点,根据需要存储并检索数据块,定期向namenode发送他们所存储的块的列表**(心跳机制)**。
5、HDFS的特性总结
- HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数**(dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M**,老版本中是64M;
- HDFS 文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件;
- NAMEMODE是HDFS集群主节点: 负责维护整个HDFS文件系统的目录树,以及每一个路径(文件)所对应的block块信息(block的id,及所在的DATANODE服务器);
- DATANODE是HDFS集群从节点: 每一个 block 都可以在多个DATANODE上存储多个副本(副本数量也可以通过参数设置 dfs.replication,默认是3);
- HDFS 是设计成适应一次写入,多次读出的场景,且不支持文件的修改;
三、HDFS组成架构
1、HDFS的架构示意图
2、NameNode和SecondaryNameNode
- NN和2NN工作机制
思考:NameNode中的元数据是存储在哪里的? - 首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。
- 这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。
- 因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。
- 但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。
- NN和2NN工作机制示意图
- 第一阶段:NameNode启动
- 第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
- 客户端对元数据进行增删改的请求。
- NameNode记录操作日志,更新滚动日志。
- NameNode在内存中对数据进行增删改。
- 第二阶段:Secondary NameNode工作
- Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。
- Secondary NameNode请求执行CheckPoint。
- NameNode滚动正在写的Edits日志。
- 将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
- Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
- 生成新的镜像文件fsimage.chkpoint。
- 拷贝fsimage.chkpoint到NameNode。
- NameNode将fsimage.chkpoint重新命名成fsimage。
3、NN和2NN工作机制详解
- Fsimage: NameNode内存中元数据序列化后形成的文件。
- Edits: 记录客户端更新元数据信息的每一步操作(可通过Edits运算出元数据)。
- 工作机制:
- NameNode启动时,先滚动Edits并生成一个空的edits.inprogress,然后加载Edits和Fsimage到内存中,此时NameNode内存就持有最新的元数据信息。Client开始对NameNode发送元数据的增删改的请求,这些请求的操作首先会被记录到edits.inprogress中(查询元数据的操作不会被记录在Edits中,因为查询操作不会更改元数据信息),如果此时NameNode挂掉,重启后会从Edits中读取元数据的信息。然后,NameNode会在内存中执行元数据的增删改的操作。
- 由于Edits中记录的操作会越来越多,Edits文件会越来越大,导致NameNode在启动加载Edits时会很慢,所以需要对Edits和Fsimage进行合并(所谓合并,就是将Edits和Fsimage加载到内存中,照着Edits中的操作一步步执行,最终形成新的Fsimage)。SecondaryNameNode的作用就是帮助NameNode进行Edits和Fsimage的合并工作。
- SecondaryNameNode首先会询问NameNode是否需要CheckPoint(触发CheckPoint需要满足两个条件中的任意一个,定时时间到和Edits中数据写满了)。直接带回NameNode是否检查结果。SecondaryNameNode执行CheckPoint操作,首先会让NameNode滚动Edits并生成一个空的edits.inprogress,滚动Edits的目的是给Edits打个标记,以后所有新的操作都写入edits.inprogress,其他未合并的Edits和Fsimage会拷贝到SecondaryNameNode的本地,然后将拷贝的Edits和Fsimage加载到内存中进行合并,生成fsimage.chkpoint,然后将fsimage.chkpoint拷贝给NameNode,重命名为Fsimage后替换掉原来的Fsimage。NameNode在启动时就只需要加载之前未合并的Edits和Fsimage即可,因为合并过的Edits中的元数据信息已经被记录在Fsimage中。
4、DataNode
- DataNode工作机制示意图
- DataNode工作流程
- 一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
- DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息。
- 心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。
- 集群运行中可以安全加入和退出一些机器。
- 数据完整性
如下是DataNode节点保证数据完整性的方法。 - 当DataNode读取Block的时候,它会计算CheckSum。
- 如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏。
- Client读取其他DataNode上的Block。
- DataNode在其文件创建后周期验证CheckSum。
四、HDFS 2.X新特性
1、集群间数据拷贝
- scp实现两个远程主机之间的文件复制
scp -r hello.txt root@hadoop103:/user/atguigu/hello.txt // 推 push
scp -r root@hadoop103:/user/atguigu/hello.txt hello.txt // 拉 pull - 通过本地主机中转实现两个远程主机的文件复制(如果在两个远程主机之间ssh没有配置的情况下可以使用该方式)。
scp -r root@hadoop103:/user/atguigu/hello.txt root@hadoop104:/user/atguigu - 采用distcp命令实现两个Hadoop集群之间的递归数据复制
bin/hadoop distcp
hdfs://haoop102:9000/user/atguigu/hello.txt
hdfs://hadoop103:9000/user/atguigu/hello.txt
2、小文件存档
3、小文件存档案例实操
- 需要启动YARN进程
start-yarn.sh - 归档文件
把/user/xxxx/input目录里面的所有文件归档成一个叫input.har的归档文件,并把归档后文件存储到/user/xxxx/output路径下。
bin/hadoop archive -archiveName input.har –p /user/xxxx/input /user/xxxx/output - 查看归档
hadoop fs -lsr /user/xxxx/output/input.har
hadoop fs -lsr har:///user/xxxx/output/input.har - 解归档文件
hadoop fs -cp har:///user/xxxx/output/input.har/* /user/xxxx
五、HDFS HA高可用
1、HA概述
- 所谓HA(High Available),即高可用(7*24小时不中断服务)。
- 实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
- Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。
- NameNode主要在以下两个方面影响HDFS集群
(1). NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启
(2). NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用 - HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
2、HDFS-HA工作机制
通过双NameNode消除单点故障
3、HDFS-HA工作要点
- 元数据管理方式需要改变
- 内存中各自保存一份元数据;
- Edits日志只有Active状态的NameNode节点可以做写操作;
- 两个NameNode都可以读取Edits;
- 共享的Edits放在一个共享存储中管理(qjournal和NFS两个主流实现);
- 需要一个状态管理功能模块
- 实现了一个zkfailover,常驻在每一个namenode所在的节点,每一个zkfailover负责监控自己所在NameNode节点,利用zk进行状态标识,当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brain split现象的发生。
4、HDFS-HA自动故障转移工作机制
- 接下来如何配置部署HA自动进行故障转移
- 自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程
- 如下图所示,ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。HA的自动故障转移依赖于ZooKeeper的以下功能:
1)故障检测: 集群中的每个NameNode在ZooKeeper中维护了一个持久会话,如果机器崩溃,ZooKeeper中的会话将终止,ZooKeeper通知另一个NameNode需要触发故障转移。
2)现役NameNode选择: ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。如果目前现役NameNode崩溃,另一个节点可能从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。ZKFC是自动故障转移中的另一个新组件,是ZooKeeper的客户端,也监视和管理NameNode的状态。
每个运行NameNode的主机也运行了一个ZKFC进程,ZKFC负责:
1)健康监测: ZKFC使用一个健康检查命令定期地ping与之在相同主机的NameNode,只要该NameNode及时地回复健康状态,ZKFC认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。
2)ZooKeeper会话管理: 当本地NameNode是健康的,ZKFC保持一个在ZooKeeper中打开的会话。如果本地NameNode处于active状态,ZKFC也保持一个特殊的znode锁,该锁使用了ZooKeeper对短暂节点的支持,如果会话终止,锁节点将自动删除。
3)基于ZooKeeper的选择: 如果本地NameNode是健康的,且ZKFC发现没有其它的节点当前持有znode锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地NameNode为Active。故障转移进程与前面描述的手动故障转移相似,首先如果必要保护之前的现役NameNode,然后本地NameNode转换为Active状态。
对以前的知识回顾,加深基础知识!
学习来自:尚硅谷大数据学习视频
每天进步一点点,也许某一天你也会变得那么渺小!!!