You are viewing a plain text version of this content. The canonical link for it is here.
Posted to hdfs-issues@hadoop.apache.org by "Chen Liang (JIRA)" <ji...@apache.org> on 2018/02/06 00:51:00 UTC

[jira] [Comment Edited] (HDFS-10453) ReplicationMonitor thread could stuck for long time due to the race between replication and delete of same file in a large cluster.

    [ https://issues.apache.org/jira/browse/HDFS-10453?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16353143#comment-16353143 ] 

Chen Liang edited comment on HDFS-10453 at 2/6/18 12:50 AM:
------------------------------------------------------------

This is a very tricky case, thanks [~hexiaoqiao] for working on this, really appreciate! I've only looked through v6 patch on branch-2.7, and I've got a question.

Given the change in {{BlockPlacementPolicyDefault#chooseTarget}} that, if the size is {{NO_ACK}}, it immediately returns an empty array, do we still really need the change in {{BlockManager#computeReplicationWorkForBlocks}}? Because with the change in {{chooseTarget}}, I think {{rw.chooseTargets(...);}} would set {{rw.targets}} to empty array, then in {{computeReplicationWorkForBlocks}}, {{if(targets == null || targets.length == 0)}} will be true and the {{rw}} gets skipped.

In addition, the check {{blocksize == BlockCommand.NO_ACK}} in {{BlockPlacementPolicyDefault}} seems a bit hacky. Because I think this flag {{NO_ACK}} only specifically means "an indicator of no need for DN to ack", but we are using it here as "an indicator that the block does not need placement". Can't think of a better easy alternative though, ideally, we may need another flag to indicate blocks being removed. But for now at least we can do something to make this easier to track in the future, such as:
 1. add some explanation comments on what this check is about, i.e. why NO_ACK is against blockSize.
 2. maybe move this check to merge in the check in L196 {{if (numOfReplicas == 0 || clusterMap.getNumOfLeaves()==0)}}


was (Author: vagarychen):
This is a very tricky case, thanks [~hexiaoqiao] for working on this, really appreciate! I've only looked through v6 patch on branch-2.7, and I've got a question.

Given the change in {{BlockPlacementPolicyDefault#chooseTarget}} that, if the size is {{NO_ACK}}, it immediately returns an empty array, do we still really need the change in {{BlockManager#computeReplicationWorkForBlocks}}? Because with the change in {{chooseTarget}}, I think {{rw.chooseTargets(...);}} would set {{rw.targets}} to empty array, then in {{computeReplicationWorkForBlocks}}, {{if(targets == null || targets.length == 0)}} will be true and the {{rw}} gets skipped, this invalidate rw will be eventually be removed from {{neededReplications}} anyway.

In addition, the check {{blocksize == BlockCommand.NO_ACK}} in {{BlockPlacementPolicyDefault}} seems a bit hacky. Because I think this flag {{NO_ACK}} only specifically means "an indicator of no need for DN to ack", but we are using it here as "an indicator that the block does not need placement". Can't think of a better easy alternative though, ideally, we may need another flag to indicate blocks being removed. But for now at least we can do something to make this easier to track in the future, such as:
1. add some explanation comments on what this check is about, i.e. why NO_ACK is against blockSize.
2. maybe move this check to merge in the check in L196 {{if (numOfReplicas == 0 || clusterMap.getNumOfLeaves()==0)}}

> ReplicationMonitor thread could stuck for long time due to the race between replication and delete of same file in a large cluster.
> -----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HDFS-10453
>                 URL: https://issues.apache.org/jira/browse/HDFS-10453
>             Project: Hadoop HDFS
>          Issue Type: Bug
>          Components: namenode
>    Affects Versions: 2.4.1, 2.5.2, 2.7.1, 2.6.4
>            Reporter: He Xiaoqiao
>            Assignee: He Xiaoqiao
>            Priority: Major
>             Fix For: 2.7.6
>
>         Attachments: HDFS-10453-branch-2.001.patch, HDFS-10453-branch-2.003.patch, HDFS-10453-branch-2.7.004.patch, HDFS-10453-branch-2.7.005.patch, HDFS-10453-branch-2.7.006.patch, HDFS-10453.001.patch
>
>
> ReplicationMonitor thread could stuck for long time and loss data with little probability. Consider the typical scenario:
> (1) create and close a file with the default replicas(3);
> (2) increase replication (to 10) of the file.
> (3) delete the file while ReplicationMonitor is scheduling blocks belong to that file for replications.
> if ReplicationMonitor stuck reappeared, NameNode will print log as:
> {code:xml}
> 2016-04-19 10:20:48,083 WARN org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy: Failed to place enough replicas, still in need of 7 to reach 10 (unavailableStorages=[], storagePolicy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}, newBlock=false) For more information, please enable DEBUG log level on org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy
> ......
> 2016-04-19 10:21:17,184 WARN org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy: Failed to place enough replicas, still in need of 7 to reach 10 (unavailableStorages=[DISK], storagePolicy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}, newBlock=false) For more information, please enable DEBUG log level on org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy
> 2016-04-19 10:21:17,184 WARN org.apache.hadoop.hdfs.protocol.BlockStoragePolicy: Failed to place enough replicas: expected size is 7 but only 0 storage types can be selected (replication=10, selected=[], unavailable=[DISK, ARCHIVE], removed=[DISK, DISK, DISK, DISK, DISK, DISK, DISK], policy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]})
> 2016-04-19 10:21:17,184 WARN org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy: Failed to place enough replicas, still in need of 7 to reach 10 (unavailableStorages=[DISK, ARCHIVE], storagePolicy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}, newBlock=false) All required storage types are unavailable:  unavailableStorages=[DISK, ARCHIVE], storagePolicy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}
> {code}
> This is because 2 threads (#NameNodeRpcServer and #ReplicationMonitor) process same block at the same moment.
> (1) ReplicationMonitor#computeReplicationWorkForBlocks get blocks to replicate and leave the global lock.
> (2) FSNamesystem#delete invoked to delete blocks then clear the reference in blocksmap, needReplications, etc. the block's NumBytes will set NO_ACK(Long.MAX_VALUE) which is used to indicate that the block deletion does not need explicit ACK from the node. 
> (3) ReplicationMonitor#computeReplicationWorkForBlocks continue to chooseTargets for the same blocks and no node will be selected after traverse whole cluster because  no node choice satisfy the goodness criteria (remaining spaces achieve required size Long.MAX_VALUE). 
> During of stage#3 ReplicationMonitor stuck for long time, especial in a large cluster. invalidateBlocks & neededReplications continues to grow and no consumes. it will loss data at the worst.
> This can mostly be avoided by skip chooseTarget for BlockCommand.NO_ACK block and remove it from neededReplications.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: hdfs-issues-unsubscribe@hadoop.apache.org
For additional commands, e-mail: hdfs-issues-help@hadoop.apache.org