Hadoop核心之HDFS
在看HDFS的设计架构之前,先看一些基本概念:
基本概念
- 块(Block)
- NameNode
- DataNode
块逻辑上是一个固定大小的存储单元,HDFS的文件被分成块进行存储,HDFS块的默认大小为64MB,文件在传输过来的时候,被分成块进行存储,块是文件存储处理的逻辑单元,做软件的备份查找,也都是按照块来进行处理的
HDFS中有两类节点,分别为: NameNode和DataNode
NameNode是一个管理节点,存放文件元数据,元数据包括两个部分:其一是文件与数据块的映射表,其二是数据块与数据节点的映射表。
在下面这个图里面,NameNode是唯一一个管理节点,这个节点存放元数据,客户查询访问请求,客户端会向NameNode请求元数据,返回的查询结果,就会知道这块的文件是存储在哪一些的节点上面,然后从相应的节点拿数据块(图中的读取数据块),得到数据块后,然后组装,再拼装成之前想要的文件
第二类节点DataNode是HDFS的工作节点,用来存放真正数据块的。
下图中机架1中有3个DataNode,机架2中有两个DataNode
数据管理策略
HDFS的数据管理,讲究的是块的放置,它不是随机存放的,而是有一定的策略的。
对于任何一个数据块,都是存放3份(图中机架1和2中的A、B、C、D、E都是三份)
HDFS这样存储数据块,是为了保证硬件上的容错,就是任何一个节点都可能发生故障,但是在出现故障之后,我们要保证数据不能丢失,所以它这个数据块的多份冗余。
图中的ABCDE都代表了一个64M的数据块,对于hadoop来说,它默认把每一个数据块保留3份,如何放这3份呢?其中有两份是放在同一个机架上的,还有一份是放在另外一个机架上的。比如看数据块C,其中两份实在机架1上放着,还有一份在机架2上放着。
如果机架1中的DataNode1挂掉了,那么A、C以及D都可以在相同机架或者机架2上找到
如果整个机架1都挂掉了,那么我们还可以在另外一个机架上找到数据块,图中ABCDE块都可以在机架2上找到
这样的数据块放置策略就可以确保数据可靠!
接下来是:心跳检测
所谓的心跳检测就是NameNode和DataNode之间有一个心跳协议,即每隔多少秒钟,DateNode定期的向NameNode汇报自己的状况(比如:网络有没有短?是否以已经关机了?是否当机了?等等),这些状态就是以一个心跳协议发送给NameNode的。
红色的线(DateNode定期的向NameNode汇报自己的状况)
这样,NameNode就知道这个集群中,哪些节点已经挂掉了,哪些是健康的。
还有一个概念是:二级NameNode(图中红色框起来的那个)
为了保证NameNode中的元数据不会丢失,同时做了一个备份(二级NameNode了的啦),元数据会定期的同步到SecondaryNameNode中,在大部分情况下即NameNode正常的情况下,SecondaryNameNode只是一个备份,不会接收请求,一旦NameNode发生故障,失效了,那么SecondaryNameNode会进行同步,切换,替换NameNode,用SecondaryNameNode保证NameNode的高可用性
这些是HDFS提供的一些数据管理策略
HDFS中文件的读写操作
HDFS中文件读取的流程
客户端(可能是一个JAVA程序,也可能是命令行等等)向NameNode发起一个文件读取请求,把文件名和文件的路径告诉NameNode
NameNode查询元数据,根据元数据返回客户端,这个时候,客户端就会知道这个文件包含哪些块以及这些块分别会在哪些DataNode中可以找得到
比如文件中包含A块:那么客户端就会知道A分别在DataNode1、DataNode2以及DataNode4上存放着
知道了文件包含哪些块以及块在哪些DataNode上存放,这个时候客户端直接访问这些DataNode来读取Block
接下来,进行组装,组装完成后,那么读取就完成了!HDFS中写入文件的流程
1.写入文件,首先把文件要拆分成64M大小的块,拆分之后,客户端去通知NameNode,然后NameNode会找到一些可用的DataNode(当前在线的且有足够磁盘空间的)来存放这些块
2.NameNode返回DataNodes给客户端
3.客户端根据返回的DataNodes,对这些块进行写入,首先写第一个数据块
4.在写入第一个块之后,要进行流水线复制。如下图:在写完C块之后,通过流水线管道进行复制C块到DataNode3和DataNode4节点上
5.在完成复制之后,再更新元数据, 这个是完成了 创建一个新的数据块,这样保证了NameNode中的元数据都是最新的状态,这是写完第一个块的流程,写剩下的块数据流程就是:写,复制,更新。
这是HDFS写文件的整个流程!
HDFS特点
上面提到了HDFS的设计架构和文件的读写操作流程,那HDFS和传统的文件系统相比有啥特点呢??
- 数据冗余,硬件容错(三份数据)
- 流式数据访问(一次写入,多次读取,一旦写入,不能被随机修改,也没办法修改,除非删掉之前写的块,然后重新追加写入一个新的块)
- 适合存储大文件(最初设计的目标就是存储大文件的,如果是一大批小文件,那么NameNode的压力负载会特别大,冗余太多了)
- 使用性和局限性
- 适合数据批量读写,吞吐量高
- 不适合交互式应用,低延迟很难满足(比如数据库这种应用)
- 适合一次写入,多次读取,顺序读写
- 不支持多用户并发写相同文件