Skip to content

Commit 9956d18

Browse files
committed
HDFS-13736. BlockPlacementPolicyDefault can not choose favored nodes when 'dfs.namenode.block-placement-policy.default.prefer-local-node' set to false. Contributed by hu xiaodong.
1 parent f29481f commit 9956d18

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

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

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,10 @@ protected void chooseFavouredNodes(String src, int numOfReplicas,
234234
DatanodeDescriptor favoredNode = favoredNodes.get(i);
235235
// Choose a single node which is local to favoredNode.
236236
// 'results' is updated within chooseLocalNode
237-
final DatanodeStorageInfo target =
238-
chooseLocalStorage(favoredNode, favoriteAndExcludedNodes, blocksize,
239-
maxNodesPerRack, results, avoidStaleNodes, storageTypes, false);
237+
final DatanodeStorageInfo target = chooseLocalOrFavoredStorage(
238+
favoredNode, true, favoriteAndExcludedNodes, blocksize,
239+
maxNodesPerRack, results, avoidStaleNodes, storageTypes);
240+
240241
if (target == null) {
241242
LOG.warn("Could not find a target for file " + src
242243
+ " with favored node " + favoredNode);
@@ -545,16 +546,41 @@ protected DatanodeStorageInfo chooseLocalStorage(Node localMachine,
545546
List<DatanodeStorageInfo> results, boolean avoidStaleNodes,
546547
EnumMap<StorageType, Integer> storageTypes)
547548
throws NotEnoughReplicasException {
549+
return chooseLocalOrFavoredStorage(localMachine, false,
550+
excludedNodes, blocksize, maxNodesPerRack, results, avoidStaleNodes,
551+
storageTypes);
552+
}
553+
554+
/**
555+
* Choose storage of local or favored node.
556+
* @param localOrFavoredNode local or favored node
557+
* @param isFavoredNode if target node is favored node
558+
* @param excludedNodes datanodes that should not be considered as targets
559+
* @param blocksize size of the data to be written
560+
* @param maxNodesPerRack max nodes allowed per rack
561+
* @param results the target nodes already chosen
562+
* @param avoidStaleNodes avoid stale nodes in replica choosing
563+
* @param storageTypes storage type to be considered for target
564+
* @return storage of local or favored node (not chosen node)
565+
* @throws NotEnoughReplicasException
566+
*/
567+
protected DatanodeStorageInfo chooseLocalOrFavoredStorage(
568+
Node localOrFavoredNode, boolean isFavoredNode, Set<Node> excludedNodes,
569+
long blocksize, int maxNodesPerRack, List<DatanodeStorageInfo> results,
570+
boolean avoidStaleNodes, EnumMap<StorageType, Integer> storageTypes)
571+
throws NotEnoughReplicasException {
548572
// if no local machine, randomly choose one node
549-
if (localMachine == null) {
573+
if (localOrFavoredNode == null) {
550574
return chooseRandom(NodeBase.ROOT, excludedNodes, blocksize,
551575
maxNodesPerRack, results, avoidStaleNodes, storageTypes);
552576
}
553-
if (preferLocalNode && localMachine instanceof DatanodeDescriptor
554-
&& clusterMap.contains(localMachine)) {
555-
DatanodeDescriptor localDatanode = (DatanodeDescriptor) localMachine;
577+
if ((preferLocalNode || isFavoredNode)
578+
&& localOrFavoredNode instanceof DatanodeDescriptor
579+
&& clusterMap.contains(localOrFavoredNode)) {
580+
DatanodeDescriptor localDatanode =
581+
(DatanodeDescriptor) localOrFavoredNode;
556582
// otherwise try local machine first
557-
if (excludedNodes.add(localMachine) // was not in the excluded list
583+
if (excludedNodes.add(localOrFavoredNode) // was not in the excluded list
558584
&& isGoodDatanode(localDatanode, maxNodesPerRack, false,
559585
results, avoidStaleNodes)) {
560586
for (Iterator<Map.Entry<StorageType, Integer>> iter = storageTypes
@@ -574,7 +600,7 @@ && isGoodDatanode(localDatanode, maxNodesPerRack, false,
574600
return localStorage;
575601
}
576602
}
577-
}
603+
}
578604
}
579605
return null;
580606
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,29 @@ public void testChooseExcessReplicaApartFromFavoredNodes() throws Exception {
15181518
}
15191519
}
15201520

1521+
@Test
1522+
public void testChooseFromFavoredNodesWhenPreferLocalSetToFalse() {
1523+
((BlockPlacementPolicyDefault) replicator).setPreferLocalNode(false);
1524+
try {
1525+
DatanodeStorageInfo[] targets;
1526+
List<DatanodeDescriptor> expectedTargets = new ArrayList<>();
1527+
expectedTargets.add(dataNodes[0]);
1528+
expectedTargets.add(dataNodes[2]);
1529+
List<DatanodeDescriptor> favouredNodes = new ArrayList<>();
1530+
favouredNodes.add(dataNodes[0]);
1531+
favouredNodes.add(dataNodes[2]);
1532+
targets = chooseTarget(2, dataNodes[3], null,
1533+
favouredNodes);
1534+
assertEquals(targets.length, 2);
1535+
for (int i = 0; i < targets.length; i++) {
1536+
assertTrue("Target should be a part of Expected Targets",
1537+
expectedTargets.contains(targets[i].getDatanodeDescriptor()));
1538+
}
1539+
} finally {
1540+
((BlockPlacementPolicyDefault) replicator).setPreferLocalNode(true);
1541+
}
1542+
}
1543+
15211544
private DatanodeStorageInfo[] chooseTarget(int numOfReplicas,
15221545
DatanodeDescriptor writer, Set<Node> excludedNodes,
15231546
List<DatanodeDescriptor> favoredNodes) {

0 commit comments

Comments
 (0)