Skip to content

Commit 04ee18e

Browse files
committed
HDFS-7742. Favoring decommissioning node for replication can cause a block to stay
underreplicated for long periods. Contributed by Nathan Roberts.
1 parent ae3e8c6 commit 04ee18e

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,9 @@ Release 2.7.0 - UNRELEASED
829829
HDFS-7410. Support CreateFlags with append() to support hsync() for
830830
appending streams (Vinayakumar B via Colin P. McCabe)
831831

832+
HDFS-7742. Favoring decommissioning node for replication can cause a block
833+
to stay underreplicated for long periods (Nathan Roberts via kihwal)
834+
832835
OPTIMIZATIONS
833836

834837
HDFS-7454. Reduce memory footprint for AclEntries in NameNode.

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,8 @@ else if (excessBlocks != null && excessBlocks.contains(block)) {
16371637
// If so, do not select the node as src node
16381638
if ((nodesCorrupt != null) && nodesCorrupt.contains(node))
16391639
continue;
1640-
if(priority != UnderReplicatedBlocks.QUEUE_HIGHEST_PRIORITY
1640+
if(priority != UnderReplicatedBlocks.QUEUE_HIGHEST_PRIORITY
1641+
&& !node.isDecommissionInProgress()
16411642
&& node.getNumberOfBlocksToBeReplicated() >= maxReplicationStreams)
16421643
{
16431644
continue; // already reached replication limit
@@ -1652,13 +1653,12 @@ else if (excessBlocks != null && excessBlocks.contains(block)) {
16521653
// never use already decommissioned nodes
16531654
if(node.isDecommissioned())
16541655
continue;
1655-
// we prefer nodes that are in DECOMMISSION_INPROGRESS state
1656-
if(node.isDecommissionInProgress() || srcNode == null) {
1656+
1657+
// We got this far, current node is a reasonable choice
1658+
if (srcNode == null) {
16571659
srcNode = node;
16581660
continue;
16591661
}
1660-
if(srcNode.isDecommissionInProgress())
1661-
continue;
16621662
// switch to a different node randomly
16631663
// this to prevent from deterministically selecting the same node even
16641664
// if the node failed to replicate the block on previous iterations

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockManager.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,48 @@ public void testHighestPriReplSrcChosenDespiteMaxReplLimit() throws Exception {
534534
UnderReplicatedBlocks.QUEUE_HIGHEST_PRIORITY));
535535
}
536536

537+
@Test
538+
public void testFavorDecomUntilHardLimit() throws Exception {
539+
bm.maxReplicationStreams = 0;
540+
bm.replicationStreamsHardLimit = 1;
541+
542+
long blockId = 42; // arbitrary
543+
Block aBlock = new Block(blockId, 0, 0);
544+
List<DatanodeDescriptor> origNodes = getNodes(0, 1);
545+
// Add the block to the first node.
546+
addBlockOnNodes(blockId,origNodes.subList(0,1));
547+
origNodes.get(0).startDecommission();
548+
549+
List<DatanodeDescriptor> cntNodes = new LinkedList<DatanodeDescriptor>();
550+
List<DatanodeStorageInfo> liveNodes = new LinkedList<DatanodeStorageInfo>();
551+
552+
assertNotNull("Chooses decommissioning source node for a normal replication"
553+
+ " if all available source nodes have reached their replication"
554+
+ " limits below the hard limit.",
555+
bm.chooseSourceDatanode(
556+
aBlock,
557+
cntNodes,
558+
liveNodes,
559+
new NumberReplicas(),
560+
UnderReplicatedBlocks.QUEUE_UNDER_REPLICATED));
561+
562+
563+
// Increase the replication count to test replication count > hard limit
564+
DatanodeStorageInfo targets[] = { origNodes.get(1).getStorageInfos()[0] };
565+
origNodes.get(0).addBlockToBeReplicated(aBlock, targets);
566+
567+
assertNull("Does not choose a source decommissioning node for a normal"
568+
+ " replication when all available nodes exceed the hard limit.",
569+
bm.chooseSourceDatanode(
570+
aBlock,
571+
cntNodes,
572+
liveNodes,
573+
new NumberReplicas(),
574+
UnderReplicatedBlocks.QUEUE_UNDER_REPLICATED));
575+
}
576+
577+
578+
537579
@Test
538580
public void testSafeModeIBR() throws Exception {
539581
DatanodeDescriptor node = spy(nodes.get(0));

0 commit comments

Comments
 (0)