大醉和尚  
qq:3262641915,如有问题,欢迎讨论.

hadoop 删除文件流程

当通过cli执行删除文件操作时,具体namenode与datanode工作详解如下:

namenode端:
1.cli提交 删除文件 command;
2.FileSystem会调用具体delete操作;
3.delete操作会由DFSClient通过RPC将delete请求发送给NameNode;
4.nameNode接收请求后,会该操作交由namesystem(名字空间)来处理;
5.nameSystem会首先校验权限,其次校验namenode状态是否为active。然后从namesystem、blockMap中移除删除的目录或文件,同时将待移除的block添加到BlockManager.invalidateBlocks(内部定义数据结构)中;该结构维护某个具体的DataNode与待删除数据块之间映射(Map);
6.其中blockManager中的ReplicationMonitor会周期从BlockManager.invalidateBlocks结构中选出若干DataNode(默认选择集群live节点总数的32%)节点,然后从该节点上待删除的数据块列表中选择出一次性最多删除数据块大小(默认1000)的数据块添加到具体的DataNodeDescriptor.invalidateBlocks(HashSet结构)对象中,同时删除BlockMap.invalidateBlocks对应的数据块;该过程将BlockMap中管理的invalidateBlocks上待删除的数据块分多次的添加对应的DataNodeDescriptor.invalidateBlocks中,待相应的DataNode发送心跳时NameNode会直接通过DataNodeDescriptor中的invalidateBlocks结构中选出本次心跳需要删除的数据块。这么做好处 1.加快对节点心跳的响应时间;2. 分多次是为了避免某个DataNode因一次删除过多数据块导致服务性能下降; 3.限制DataNode个数是为避免因删除数据节点过多导致集群性能下降;
datanode端:
1.DataNode周期性向NameNode 发送心跳信息,心跳信息主要包含节点storageInfo;
2.接收NameNode返回的Command,其中Command分为INVLIDATE(执行删除操作)、TRANSFER(执行数据块移动操作)、REGISTER(执行节点注册)、RECOVERBLOCK(修复block操作)等;
3.接收返回的Command,DataNode会根据Command类型执行响应的操作,在这里处理删除操作(INVALIDATE),DataNode会掉用BlockPoolSliceScanner执行delete操作,从DataNode的blockMap中删除响应数据块,然后异步删除本地磁盘上的文件,待删除完后会通知DataNode该数据块已经删除并将删除数据块添加到用于存放数据块变化的数据结构pendingIncrementalBRperStorage(Map),等待下次心跳是将这些变更通知NameNode;

其中namenode向datanode下发Command优先顺序:
1.REGISTER(如果该datanode没有注册或者被认为是dead状态,会优先下发该命令)
2.RECOVERBLOCK(由租约管理器检查是否该datanode上有需要进行租约恢复block,若有会将下发该Command)
3.TRANSFER、INVALIDATE(若有需要recover或者delete下发 响应命令)

根据上面的流程,可以看出当执行rm操作时,namenode中的内存结构首先会被更新,然后具体的文件删除会通过心跳机制陆续下发给相应的datanode节点执行;若某个datanode上有文件需要恢复租约会优先下发RECOVERBLOCK命令,若datanode上没有需要恢复租约的文件则下发INVALDATE命令,这时datanode才会执行真正的文件删除操作;
如果删除文件量过大(根据数据存储策略,数据会分布在较多的datanode上)且datanode上陆续的有需要恢复租约的文件操作(比如flume,mr写操作),则删除的操作会被延期处理且有可能延迟很久直到节点没有租约需要恢复;针对集群节点较多任务较多的时候执行大量的删除操作,可能存在性能隐患。
具体场景:若文件的删除在下次做强制做blockReport(默认6小时)之间都没有被删除掉(根据上面删除流程,操作是分批次进行的),那么下次blockReport就会在namenode日志中看见大量的无效块汇报;blockReport需要申请namenode writeLock,由于心跳是并发操作这时会存在大量的锁竞争,且只有当一个DataNode上的所有block处理结束后会释放该锁,因节点的待删除block数量决定处理时间及锁持有时间,这样删除量较大的节点进行心跳处理时间会较长,如果这样节点数据较多,导致HDFS namenode处理性能下降,同时新的读写任务会继续访问namenode进行创建新的读写文件或者获取文件location进行写操作时也需要申请writeLock,许多写的进程也会被阻塞甚至正在写的文件申请一个新的数据块也被阻塞,这样整个HDFS会因BlockReport中大量的InvalidataBlock导致hdfs服务超时不可用,因namenode有ha机制,zkfc会周期性的通过HealthMonitor获取一个NameNode RpcServer的代理,如果获取超时会抛出IOException,然后将NameNode状态变更为SERVICE_NOT_RESPONDING状态,同时回调ZKFailContronller.enterdState函数进行主备切换。切换后另外一个namenode会成为Active,此时datanode会向新的namenode发送心跳,同时也会越到上述场景。
从上面的删除文件流程,可以看出在集群繁忙或读写操作较多的时候,不建议一次性删除大量文件。

posted on 2022-08-08 09:18  大醉和尚  阅读(89)  评论(0编辑  收藏  举报