Hadoop分布式文件系统(HDFS)
多台计算机联网协同工作(集群)就像单台系统一样解决某种问题,我们称之为分布式系统。如名字所暗示的,计算job是分布在多台计算机上进行的。
HDFS是分布式系统的一个子集,它解决的问题是数据存储,换句话说,它们是横跨在多台计算机上的存储系统。
存储在这种文件系统上的数据字段分布在不同的节点上:你不必担心需要人工决定哪些数据存放在哪个节点。
分离元数据和数据:NameNode和DataNode
存储到文件系统里面的每个文件都有相关联的元数据,如来自WEB服务器的日志都是独立的文件。它们的元数据包括了文件名、i节点(inode)数、数据块位置等,数据则是文件的实际内容。
在传统的文件系统里面,因为文件系统不会跨越多台机器,元数据和数据存储在同一台机器上,当客户端对文件执行任何操作和需要元数据的时候,它会访问那台机器,并且给出指令执行操作,所有的事情都在单台机器上发生。在这种模式下,访问多台系统所管理的数据的唯一方法只能是,让客户端记住数据是如何分布在不同的硬盘上的,这会让客户端有状态,难以维护。
因为有状态的客户端必须互相分享状态信息,随着它们数量的增长,管理起来会变的越来越复杂。如一个客户端在一台机器上写一个文件,其它客户端为了以后访问这个文件,需要知道文件的保存位置,它们必须从第一个客户端获取信息。
为了构建一个分布式文件系统,让客户端在这种系统中使用简单,并且不需要知道其他客户端的活动,那么元数据需要在客户端以外进行维护,最简单的办法是,让文件系统自己去管理元数据,当然把元数据和数据存储在同一位置是不可行的。解决的办法是,拿出一台或者多台机器保存元数据,让剩下的机器保存文件内容。HDFS的设计就是这个理念,他有两个组件,即NameNode和DataNode。元数据存储在NameNode上,而数据存储在DataNode的集群上。NameNode不仅要管理存储在HDFS上内容的元数据,而且还需要记录一些事情,比如哪些节点是集群的一部分,某个文件有几份副本,等等,它还有决定当集群的节点宕机或者数据副本丢失的时候需要做什么。
存储在HDFS上的每份数据片有多个副本保存在不同的服务器上,本质上NameNode是HDFS的Master(主服务器),DataNode是Slave(从服务器)。
HDFS写过程
1、 客户端---->NameNode:“我想写入文件XX.txt”
2、 NameNode--->客户端:“没有问题,准备开始吧,你可以写到DataNode A、B和D,你应该直接联系DataNode B”
3、 客户端--->DataNode B:“这是xx.txt的内容。请保留一份,并且分别发送一份副本给DataNode A和D。”
DataNode B---->DataNodeA:“这是xx.txt的内容。请保留一份,并且分别发送一份副本给DataNode D。”
DataNode A--->DataNodeD:“这是xx.txt的内容,请保留一份。”
DataNode D--->DataNodeA:“确认。”
DataNode A--->DataNodeB:“确认。”
4、 DataNode B--->客户端:“确认,你的写入现在已完成。”
最早连接的DataNode把文件已写入HDFS的确认发送给客户端,文件被认为已写入HDFS,
写操作完成。此时文件仍然在DataNode内存中,还没有持久化到硬盘上。这样做出于性能方面考虑,提交所有副本到硬盘会增加完成写的操作时间,一旦数据到了内存,DataNode就会尽快持久化到硬盘上,写操作不会阻塞这里。
HDFS读过程
1、 客户端--->NameNode:“我想读取文件xx.txt。”
2、 NameNode--->客户端:“当然可以,准备开始吧,你可以从DataNode B读取block-1和DataNode C读取block-2”
3、 客户端--->NameNode B:“我想读取block-1”
客户端---->NameNode C:“我想读取block-2”
4、 NameNode B --->客户端:“block-1的内容”
NameNode C --->客户端:“block-2的内容”
通过副本快速恢复硬件故障
当一切正常时,DataNode会周期发送心跳给NameNode(默认3秒钟一次),若NameNode在预定的时间内没有收到心跳信息(默认10分钟),它会认为DataNode出问题,把它从集群中移除,并且启动一个进程去恢复故障,DataNode可能有多种原因脱离集群,如硬盘故障、主板故障和网络故障等。HDFS从这些故障中恢复的方法是一样的。
对HDFS来说,丢失一个DataNode意味着丢失了存储在它硬盘上数据块的副本。假设在任意时间总有超过一个副本存在(默认3个),故障不会导致数据丢失。当一个硬盘故障时,HDFS会检测到存储在该硬盘的数据块的副本数据低于要求,然后主动创建需要的副本,以达到满副本数状态。
跨多个DataNode切分文件
在HDFS写过程中,文件会被切分成数据块,通常每个数据块64M~128M,然后每个数据块被写入文件系统。同一个文件的不同数据块不一定保存在相同的DataNode上。实际上,不同的数据块保存到不同的DataNode是有好处的。
一、文件大小会超过单个硬盘容量,你可以先把它们切分成数据块,再分散存放到多个节点
二、把数据块分散到多个DataNode,当你对这些文件执行运算时,可以通过并行方式读取和处理文件的不同部分。
你可能想知道,如何把文件切成数据块,谁决定各个数据块应该存放到哪个DataNode。当客户端准备写文件到HDFS并询问NameNode应该把文件写到哪里时,NameNode会告诉客户端,那些可以写入数据块的DataNode。写完一批数据块后,客户端会回到NameNode获取新的DataNode列表,把下一批数据块写到新列表中的DataNode上。