目录
1.DataNode是什么?
2.DataNode做什么?
3.DataNode怎么做?
1.DataNode是什么?
Datanode是HDFS文件系统的工作节点,它们根据客户端或者是namenode的调度进行存储和检索数据,并且定期向namenode发送它们所存储的块(block)的列表。
2.DataNode做什么?
- Datanode以存储数据块(Block)的形式保存HDFS文件
- 响应客户端的读写文件请求
- 定期向NameNode汇报心跳信息、数据块汇报信息(BlockReport )、缓存数据块汇报信息(CacheReport)增量数据块块汇报信息。
- 响应NameNode返回的指令,如复制、删除、创建数据块指令
3.DataNode怎么做?
(1)HDFS的文件在DataNode上以数据块的形式存储,Hadoop1.x默认大小为64M,Hadoop2.x默认大小为128M,可以通过修改hdfs-site.xml设置块大小
<property>
<name>dfs.blocksize</name>
<value>128m</value>
</property>
<property>
<name>dfs.namenode.fs-limits.min-block-size</name>
<value>128m</value>
</property>
(2)HDFS中的chunk、packet、block
- block是最大的一个单位,它是最终存储于DataNode上的数据粒度,由dfs.block.size参数决定,默认是128M;注:这个参数由客户端配置决定;
- packet是中等的一个单位,它是数据由DFSClient流向DataNode的粒度,以dfs.write.packet.size参数为参考值,默认是64K;注:这个参数为参考值,是指真正在进行数据传输时,会以它为基准进行调整,调整的原因是一个packet有特定的结构,调整的目标是这个packet的大小刚好包含结构中的所有成员,同时也保证写到DataNode后当前block的大小不超过设定值;
- chunk是最小的一个单位,它是DFSClient到DataNode数据传输中进行数据校验的粒度,由io.bytes.per.checksum参数决定,默认是512B;
- 注:事实上一个chunk还包含4B的校验值,因而chunk写入packet时是516B;数据与检验值的比值为128:1,所以对于一个128M的block会有一个1M的校验文件与之对应;
(3)HDFS写文件流程
- Client向NameNode发起写入文件的请求
- NameNode判断文件是否存在、是否具有权限,若满足条件,NameNode先将操作写入EditLog文件中,根据配置文件设置的block大小计算出文件需要切分成多少份,并创建输出流,将这些信息返回给Client
- Client接收到NameNode的响应信息,将文件按照128M(Hadoop2.x默认128M)切割成N份,通过rpc向NameNode请求上传第一个block
- NameNode返回DataNode列表
- Client与最近的DataNode建立block传输通道,开始写入数据
- 写入数据时,HDFSOutputStream会有一个chunk buff,写满一个chunk(默认512B)后,会计算校验和(占4B),将校验和与真实数据组合起来生成一个完整的chunk(516B),并写入到packet中
- 当一个packet(默认64K)写满后,会将packet放到dataQueue队列中
- DataNode从dataQueue队列中获取一个packet后,会直接将该packet传输到下一个DataNode,并将存储成功的packet放入ack packet中
- 当一个block在DataNode存储成功后,DataNode会返回确认信息。一般而言,HDFS是强一致性,所以当所有的DataNode都返回确认信息后,才会向NameNode发送完成信息
- 接着重复上述操作开始上传第二个block
补充:
(1)机架感知(副本节点的选择)
hadoop1.x版本中的机架感知
- 第一个副本在Client所处的节点上。若Client在集群外,则第一个副本在集群中随机选取一个节点存放
- 第二个副本存储在与第一个副本不同机架上的随机节点
- 第三个副本存储在第二个副本所处机架上的其他随机节点
hadoop2.x版本中的机架感知
- 第一个副本在Client所处的节点上。若Client在集群外,则第一个副本在集群中随机选取一个节点存放
- 第二个副本存储在第一个副本所在机架的其他随机节点
- 第三个副本存储在第二个副本不同机架上的随机节点
(2)在Client向DataNode1不断传数据的过程中,倘若这时候DataNode2或者DataNode3宕机了。由于心跳机制的存在,NameNode会检测到DataNode2或者DataNode3挂掉了,而上传的文件却是需要3个副本的。所以此时NameNode会异步复制一份数据到其他正常的DataNode节点。当然,若此时挂掉的是DataNode1节点,则Client会向DataNode1不断的请求,达到一定重试时间后,Client就会放弃向DataNode1发起请求,重新向NameNode发起上传数据的请求,NameNode会返回3个正常的DataNode节点给Client,然后进行上传文件的操作。
疑问:倘若文件的副本数为3,且当前集群只有3个节点。若在上传的过程中,任一DataNode节点挂掉了,NameNode又会如何操作呢?
(4)HDFS读文件流程
- Client向NameNode发起读取文件的请求
- NameNode判断是否存在文件、是否具有权限等,若满足条件,则返回该文件数据块的位置列表
- Client接收到NameNode返回的信息,就近挑选DataNode,请求建立输入流
- DataNode向输入流写入数据
(5)心跳机制
DataNode每隔三秒汇报给namenode
判断DataNode超时的时间公式:
timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval
而默认的heartbeat.recheck.interval 大小为5分钟,dfs.heartbeat.interval默认的大小为3秒。
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒