HDFS初识
HDFS是以最少的钱买最烂的机器实现最安全的难度很高的分布式文件系统,可以看出HDFS认为机器故障是种常态,所以设计时充分考虑到单个机器故障,单个磁盘故障,单个文件丢失的情况。
HDFS主要分为client,namenode,datanode三大主题,这里的client更像传统的C/S结构中的C,因为必要时client需要维护一系列的状态,验证数据完整性等;namenode在HDFS中是个单点,是整个HDFS的心脏,他管理着HDFS的文件命名空间,管理整棵文件树的添加,修改,删除,这些都是持久化在硬盘之上的,文件里面的内容包含block的元数据;block和datanode的映射则是放在内存中,在datanode启动时和datanode正常运行中会定时的向namenode上报自己存储的block。
datanode在一个集群中一般是多个的,用于存储实际的文件数据,文件是以block的形式存储,一个block的文件大小默认为64M,选择大block的原因是减少磁盘的寻道次数,提高整体带宽和吞吐量,文件被分割成一个个block,这些block不一定放在同一个datanode中,一般会分散到各个datanode中,这样就实现了负载均衡而不会使得某几个datanode的负载过高而其他datanode有很空闲,为了防止datanode故障而丢失文件,单个block会在多个datanode中有备份,当系统设置了最小备份数或者是默认的备份数,那么在datanode定时向namenode上报自己的存储情况时,namenode能知道每一个block的备份数,当小于最小备份数时,namenode通知datanode进行相关block的备份。
HDFS正常的读写流程
读过程:
client接收到用户的读请求----->client拿着path向namenode请求文件或者block的datanode列表----->client从返回的datanode列表中选择一个离自己最近的datanode,并且向他请求数据----->datanode接到请求返回block的数据
写过程:
client接收到用户的写请求----->client接收到数据,分割成一个个block----->client请求namenode,说明写入数据大小和备份数----->namenode返回给client需要的datanode列表----->client写入第一个datanode,以packet的形式写入,一个packet一般为64k;第一个datanode写入第二个datanode,依次类推;之后每个datanode返回ack信息,第一个datanode返回所有的ack信息给client;当datanode持久化数据后向namenode汇报已经完成----->client接收到ack,检查所有datanode都写入正常,发送请求给namenode要求关闭文件----->namenode关闭文件
HDFS的容错性
HDFS错误一般有三种:datanode的错误,网络出错,namenode的错误以及单个数据块出错
每个datanode周期性地向namenode发送心跳信号,如果namenode在一定时间内没有接收到datanode的心跳的话,namenode就认为该datanode故障了,有一种情况是datanode存活着,但是因为网络出错,namenode一直没有收到datanode的心跳就认为该datanode故障了
namenode是单点,挂了就没的玩了
单个数据块在不稳定的网络传输时有可能会出错,所有在存储数据时,也存储了校验码;使用校验码校验,传输数据时传输数据和校验码,接收方计算数据的校验码,然后和传送过来的校验码进行对比,两者一致的话说明数据是正确的,当两者不一致时说明数据都是错误的,当数据错误时client会选择另外一个datanode进行读取.
因为HDFS认为错误时必须的,所以数据块在多个datanode中都存在,当一个datanode或者一个数据块错误时,namenode要求datanode进行相关的block复制使其备份数达到最小备份数。 namenode里面存储的关于block和datanode的相关信息至关重要,一切维持系统正常运行的举措都是靠这些消息进行判断的。