HDFS的租约机制 、租约管理 、租约恢复

    技术2025-03-23  25

    常见问题

    写入过程客户端崩溃怎么处理(租约恢复)?NameNode中的租约管理器?

    租约概念

    我们知道HDFS文件是write-once-read-many,并且不支持客户端的并行写操作,那么这里就需要一种机制保证对HDFS文件的互斥操作。HDFS提供了租约(Lease)机制来实现这个功能,租约是Namenode给予租约持有者(LeaseHolder, 一般是客户端)在规定时间内拥有文件权限(写文件)的合同。

     

    租约申请流程

    在HDFS中,客户端写文件时需要先从租约管理器(LeaseManager)申请一个租约,成功申请租约之后客户端就成为了租约持有者,也就拥有了对该HDFS文件的独占权限,其他客户端在该租约有效时无法打开这个HDFS文件进行操作。Namenode的租约管理器保存了HDFS文件与租约、租约与租约持有者的对应关系,租约管理器还会定期检査它维护的所有租约是否过期。租约管理器会强制收回过期的租约,所以租约持有者需要定期更新租约,维护对该文件的独占锁定。当客户端完成了对文件的写操作,关闭文件时,必须在租约管理器中释放租约。

     

    租约触发时机

    —般有三种方式会触发租约恢复。

    一是Monitor线程监控租约超过硬限制时间,主要是由于客户端打开文件之后出现故障,客户端不能更新租约,导致超时。客户端远程方法发起租约恢复,这里会将force字段置为true,也就是强制关闭文件并释放租约,而不用判断租约是否超过了软限制时间。客户端打开一个文件进行写操作,会先检査是否有别的客户端打开了这个文件,以防止多个客户端同时写这个文件。如果有别的客户端打开了这个文件,会抛岀AlreadyBeingCreatedException异常。这里的force字段设置为false。方法会判断原租约持有者是否已经软超时(softLimit),如果超时则进行租约恢复操作释放租约并关闭文件,为文件写操作做准备。

    租约恢复

    下面我们看一下租约恢复的过程,这里是在需要进行租约恢复的数据块上调用 initializeBlockRecovery()方法,该方法会遍历所有保存副本的数据节点,选取一个最近一次进行汇报的数据节点作为主恢复节点,然后向这个数据节点发送租约恢复指令,Namenode会通过心跳将租约恢复的名字节点指令下发给该恢复节点。

    主恢复数据节点接收到指令后,会调用Datanode.recoverBlock()方法开始租约恢复,这个方法首先会向数据流管道中参与租约恢复的数据节点收集副本信息,副本信息会以ReplicaRecoverylnfo对象返回给主恢复节点。然后从该数据块的所有副本中选取一个最好的状态作为所有副本恢复的目标状态(多个副本中选择最小长度作为最终更新一致的标准)。确后主恢复节点会同步所有Datanode上该数据块副本至目标状态。同步结束后,这些数据节点上的副本长度和时间戳将一致。最后,主恢复节点会向NameNode报告这次租约恢复的结果。NameNode 更新文件 block 元数据信息,收回该文件租约,并关闭文件。

    为什么在多个副本中选择最小长度作为最终更新一致的标准?

    想想写入流水线过程,如果 Client 挂掉导致写入中断后,对于流水线上的多个 DataNode 收到的数据在正常情况下应该是一致的。但在异常情况下,排在首位的收到的数据理论上最多,末位的最少,由于数据接收的确认是从末位按反方向传递到首位再到 Client 端。所以排在末位的 DataNode 上存储的数据都是实际已被确认的数据,而它上面的数据实际在不一致的情况也是最少的,所以算法里选择多个节点上最小的数据长度为标准来同步到一致状态。

     

     

    Processed: 0.010, SQL: 9