所有HDFS系列文章都收藏在此专栏中,欢迎订阅。
https://blog.csdn.net/yexiguafu/category_11153078.html
一、前置概念
① Lease(租约)
HDFS不支持客户端的并行写操作,也就是说一个文件同一时刻只能由一个客户端来写。因此就需要一种机制来保证对HDFS文件写的互斥。HDFS采用了租约(Lease)机制来实现此功能。租约的意思就是:Namenode给租约持有者(Lease Holder,一般是一个客户端)在规定时间内拥有写文件的权限的合同。
② softLimit和hardLimit
在①中我们说了,是在规定时间内拥有写文件的权限。这里面有两个时间概念。
- softLimit:软限制是写文件规定的租约超时时间,默认60秒,不可以配置
- hardLimit:硬限制是用于考虑文件关闭异常时,强制收回租约的时间,默认60分钟,不可以配置。LeaseManager类中有一个Monitor内部类定期的去检查租约的更新情况,当超过hardLimit时,会触发租约恢复机制。
③ Block Recovery(块恢复)
说块恢复之前,必须要说租约恢复。在HDFS中,客户端要想写文件,必须要获得该文件的租约。如果客户端还想要继续写文件,那么必须要在提前定义好的时间周期里(soft limit and hard limit)进行renew 租约。如果没有显式地renew租约或者客户端挂掉了,那么HDFS就会关闭这个文件并且释放掉代表这个客户端的租约,从而让其他的客户端能够写文件。这个过程就叫做lease recovery(租约恢复)。那block recovery(块恢复)呢,其实是在租约恢复里触发的一个过程。在租约恢复的过程中,只有当文件的最后一个block不是COMPLETE状态的时候对这个block进行block recovery。块恢复的目的是让存储最后一个块的副本的所有datanode上最后一个块的内容相同。
④ truncateRecovery和copyOnTruncate(如果不理解可以先跳过,后续看源码再回来看)
租约恢复的源码中,经常有这两个boolean类型的变量:truncateRecovery和copyOnTruncate。
truncateRecovery表示当前是不是对truncate操作的block进行recovery。代码如下:
// 拿到Feature
BlockUnderConstructionFeature uc =
lastBlock.getUnderConstructionFeature();
// determine if last block was intended to be truncated
BlockInfo recoveryBlock = uc.getTruncateBlock();
// 如果recoveryBlock不等于null。说明是truncate操作的block,那truncateRecovery就是true。
boolean truncateRecovery = recoveryBlock != null;
copyOnTruncate表示是否是在truncate时复制。代码如下:
boolean copyOnTruncate = truncateRecovery &&
recoveryBlock.getBlockId() != lastBlock.getBlockId();
计算这个copyOnTruncate需要两个步骤,因为是&&短路与操作,所以只有当truncateRecovery为true时才可能计算后面的表达式。我们假设truncateRecovery==true,也就是说是对truncate操作的block进行recovery。接着recoveryBlock.getBlockId() != lastBlock.getBlockId(); 这里不等于的情况是:truncate操作指定的源block和当前块不一样,因此后续需要让当前块去和源block一致。
网友评论