问一问自己,Hadoop是如何实现HDFS文件存储系统的呢?

特点:

1)大数据文件分割存储

   磁盘默认的数据块大小,是对磁盘数据读写时要求的最小单位,通常磁盘的块是512字节。文件系统构建于磁盘上,所以需要设计成磁盘块整数倍。HDFS于是就有了块的概念(block)默认大小是64M,其目的是最小化寻址开销。一个超大文件G、T、P级别,分割成若干块,但是这些块并不需要存储在同一个磁盘上,采用分布式存储逻辑,单位块可以存储在集群中任意磁盘。

2)一次写入多次读取。

3)分布式可以运行在廉价的机器上。

特点优秀,缺点也非常明显;

1)不能实时查询数据,较低延迟的查询。

2)大量小文件,小文件通常定义为远小于block size(64M)的文件,由于每个文件都产生各自的Metadata元数据,通过nameNode存储这些信息,若小文件过多会造成nameNode存储瓶颈。

3)写入更新问题,hadoop是一次写入多次读取,不支持多用户写入,若要更新也是文件追加到文件尾的方式,出现太多文件更新情况,hadoop是不支持的。

4)结构化数据,HDFS适合存储半结构化和非结构化的数据。个人理解都可以存储。

5)通常处理TB、PB级的数据,较小的话不适合使用Hadoop。

集群的主从结构:nameNode系统通常只有一个名字节点,中心服务器的角色,管理dataNode实际数据所需的元数据Metadata。dataNode数据真正存储的地方,在nameNode统一调度下进行数据块的创建、删除、复制,主要是针对block块的操作。

 

存储写入文件的过程:

1、客户端调用创建文件,HDFS调用nameNode节点,在命名空间中创建一个文件。节点首先确定原文件不存在,并且客户端有创建文件的权限,然后创建文件。

2、创建文件完成,HDFS返回的是DFSOutputStream,客户端用此开始写入数据,由DFSOutpurStream把数据分成块,写入data queue数据队列。

3、Data queuer队列中的数据由data Streamer读取,并通知nameNode节点分配数据节点,用来存储数据块(每块默认复制3块)。

4、nameNode分配的数据节点放在同一个pipeline里。data Streamer把块写入到第一个节点里,然后第一节点把数据块发送到第二个节点,最后第二个节点把数据块发送到第三个节点里。

5、DFSOutputStream 为发送出去的数据块保存ACK Queue,等待pipeline中的数据节点告知数据已写入成功。

数据块复制策略:

运行客户端的节点放一个副本(若客户端运行在集群之外,会随机选择一个节点存放第一个副本),第二个副本会放在与第一个副本不同随机机架中节点上,第三个副本与第二个副本放在相同的机架上,随机的另外一个点。提高容错性能。所有的块复制决策由nameNode统一复制,会周期性的接受集群中的数据节点心跳和块报告。

读取存储文件过程:

1、客户端通过open函数打开文件,通过调用nameNode节点得到文件的数据块信息。对于每一个数据块,nameNode节点返回保存数据库的数据节点地址。

2、DFS返回DFSDataInputStream给客户端,用来读取数据。调用 stream 的 read()函数开始读取数据。连接保存此文件第一个数据块的最近的数据节点。DataNode 从数据节点读到客户端,当此数据块读取完毕时,DFSInputStream 关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。当客户端读取完毕数据的时候,调用FSDataInputStream 的 close 函数。在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。失败的数据节点将被记录,以后不再连接。