|
@@ -23,6 +23,7 @@ import java.util.*;
|
|
|
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
|
+import org.apache.hadoop.hdfs.AddBlockFlag;
|
|
import org.apache.hadoop.fs.StorageType;
|
|
import org.apache.hadoop.fs.StorageType;
|
|
import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;
|
|
import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
@@ -111,9 +112,10 @@ public class BlockPlacementPolicyDefault extends BlockPlacementPolicy {
|
|
boolean returnChosenNodes,
|
|
boolean returnChosenNodes,
|
|
Set<Node> excludedNodes,
|
|
Set<Node> excludedNodes,
|
|
long blocksize,
|
|
long blocksize,
|
|
- final BlockStoragePolicy storagePolicy) {
|
|
|
|
|
|
+ final BlockStoragePolicy storagePolicy,
|
|
|
|
+ EnumSet<AddBlockFlag> flags) {
|
|
return chooseTarget(numOfReplicas, writer, chosenNodes, returnChosenNodes,
|
|
return chooseTarget(numOfReplicas, writer, chosenNodes, returnChosenNodes,
|
|
- excludedNodes, blocksize, storagePolicy);
|
|
|
|
|
|
+ excludedNodes, blocksize, storagePolicy, flags);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -123,13 +125,14 @@ public class BlockPlacementPolicyDefault extends BlockPlacementPolicy {
|
|
Set<Node> excludedNodes,
|
|
Set<Node> excludedNodes,
|
|
long blocksize,
|
|
long blocksize,
|
|
List<DatanodeDescriptor> favoredNodes,
|
|
List<DatanodeDescriptor> favoredNodes,
|
|
- BlockStoragePolicy storagePolicy) {
|
|
|
|
|
|
+ BlockStoragePolicy storagePolicy,
|
|
|
|
+ EnumSet<AddBlockFlag> flags) {
|
|
try {
|
|
try {
|
|
if (favoredNodes == null || favoredNodes.size() == 0) {
|
|
if (favoredNodes == null || favoredNodes.size() == 0) {
|
|
// Favored nodes not specified, fall back to regular block placement.
|
|
// Favored nodes not specified, fall back to regular block placement.
|
|
return chooseTarget(src, numOfReplicas, writer,
|
|
return chooseTarget(src, numOfReplicas, writer,
|
|
new ArrayList<DatanodeStorageInfo>(numOfReplicas), false,
|
|
new ArrayList<DatanodeStorageInfo>(numOfReplicas), false,
|
|
- excludedNodes, blocksize, storagePolicy);
|
|
|
|
|
|
+ excludedNodes, blocksize, storagePolicy, flags);
|
|
}
|
|
}
|
|
|
|
|
|
Set<Node> favoriteAndExcludedNodes = excludedNodes == null ?
|
|
Set<Node> favoriteAndExcludedNodes = excludedNodes == null ?
|
|
@@ -164,7 +167,7 @@ public class BlockPlacementPolicyDefault extends BlockPlacementPolicy {
|
|
DatanodeStorageInfo[] remainingTargets =
|
|
DatanodeStorageInfo[] remainingTargets =
|
|
chooseTarget(src, numOfReplicas, writer,
|
|
chooseTarget(src, numOfReplicas, writer,
|
|
new ArrayList<DatanodeStorageInfo>(numOfReplicas), false,
|
|
new ArrayList<DatanodeStorageInfo>(numOfReplicas), false,
|
|
- favoriteAndExcludedNodes, blocksize, storagePolicy);
|
|
|
|
|
|
+ favoriteAndExcludedNodes, blocksize, storagePolicy, flags);
|
|
for (int i = 0; i < remainingTargets.length; i++) {
|
|
for (int i = 0; i < remainingTargets.length; i++) {
|
|
results.add(remainingTargets[i]);
|
|
results.add(remainingTargets[i]);
|
|
}
|
|
}
|
|
@@ -179,7 +182,7 @@ public class BlockPlacementPolicyDefault extends BlockPlacementPolicy {
|
|
// Fall back to regular block placement disregarding favored nodes hint
|
|
// Fall back to regular block placement disregarding favored nodes hint
|
|
return chooseTarget(src, numOfReplicas, writer,
|
|
return chooseTarget(src, numOfReplicas, writer,
|
|
new ArrayList<DatanodeStorageInfo>(numOfReplicas), false,
|
|
new ArrayList<DatanodeStorageInfo>(numOfReplicas), false,
|
|
- excludedNodes, blocksize, storagePolicy);
|
|
|
|
|
|
+ excludedNodes, blocksize, storagePolicy, flags);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -213,7 +216,8 @@ public class BlockPlacementPolicyDefault extends BlockPlacementPolicy {
|
|
boolean returnChosenNodes,
|
|
boolean returnChosenNodes,
|
|
Set<Node> excludedNodes,
|
|
Set<Node> excludedNodes,
|
|
long blocksize,
|
|
long blocksize,
|
|
- final BlockStoragePolicy storagePolicy) {
|
|
|
|
|
|
+ final BlockStoragePolicy storagePolicy,
|
|
|
|
+ EnumSet<AddBlockFlag> addBlockFlags) {
|
|
if (numOfReplicas == 0 || clusterMap.getNumOfLeaves()==0) {
|
|
if (numOfReplicas == 0 || clusterMap.getNumOfLeaves()==0) {
|
|
return DatanodeStorageInfo.EMPTY_ARRAY;
|
|
return DatanodeStorageInfo.EMPTY_ARRAY;
|
|
}
|
|
}
|
|
@@ -226,17 +230,42 @@ public class BlockPlacementPolicyDefault extends BlockPlacementPolicy {
|
|
numOfReplicas = result[0];
|
|
numOfReplicas = result[0];
|
|
int maxNodesPerRack = result[1];
|
|
int maxNodesPerRack = result[1];
|
|
|
|
|
|
- final List<DatanodeStorageInfo> results = new ArrayList<>(chosenStorage);
|
|
|
|
for (DatanodeStorageInfo storage : chosenStorage) {
|
|
for (DatanodeStorageInfo storage : chosenStorage) {
|
|
// add localMachine and related nodes to excludedNodes
|
|
// add localMachine and related nodes to excludedNodes
|
|
addToExcludedNodes(storage.getDatanodeDescriptor(), excludedNodes);
|
|
addToExcludedNodes(storage.getDatanodeDescriptor(), excludedNodes);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ List<DatanodeStorageInfo> results = null;
|
|
|
|
+ Node localNode = null;
|
|
boolean avoidStaleNodes = (stats != null
|
|
boolean avoidStaleNodes = (stats != null
|
|
&& stats.isAvoidingStaleDataNodesForWrite());
|
|
&& stats.isAvoidingStaleDataNodesForWrite());
|
|
- final Node localNode = chooseTarget(numOfReplicas, writer, excludedNodes,
|
|
|
|
- blocksize, maxNodesPerRack, results, avoidStaleNodes, storagePolicy,
|
|
|
|
- EnumSet.noneOf(StorageType.class), results.isEmpty());
|
|
|
|
|
|
+ boolean avoidLocalNode = (addBlockFlags != null
|
|
|
|
+ && addBlockFlags.contains(AddBlockFlag.NO_LOCAL_WRITE)
|
|
|
|
+ && writer != null
|
|
|
|
+ && !excludedNodes.contains(writer));
|
|
|
|
+ // Attempt to exclude local node if the client suggests so. If no enough
|
|
|
|
+ // nodes can be obtained, it falls back to the default block placement
|
|
|
|
+ // policy.
|
|
|
|
+ if (avoidLocalNode) {
|
|
|
|
+ results = new ArrayList<>(chosenStorage);
|
|
|
|
+ Set<Node> excludedNodeCopy = new HashSet<>(excludedNodes);
|
|
|
|
+ excludedNodeCopy.add(writer);
|
|
|
|
+ localNode = chooseTarget(numOfReplicas, writer,
|
|
|
|
+ excludedNodeCopy, blocksize, maxNodesPerRack, results,
|
|
|
|
+ avoidStaleNodes, storagePolicy,
|
|
|
|
+ EnumSet.noneOf(StorageType.class), results.isEmpty());
|
|
|
|
+ if (results.size() < numOfReplicas) {
|
|
|
|
+ // not enough nodes; discard results and fall back
|
|
|
|
+ results = null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (results == null) {
|
|
|
|
+ results = new ArrayList<>(chosenStorage);
|
|
|
|
+ localNode = chooseTarget(numOfReplicas, writer, excludedNodes,
|
|
|
|
+ blocksize, maxNodesPerRack, results, avoidStaleNodes,
|
|
|
|
+ storagePolicy, EnumSet.noneOf(StorageType.class), results.isEmpty());
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!returnChosenNodes) {
|
|
if (!returnChosenNodes) {
|
|
results.removeAll(chosenStorage);
|
|
results.removeAll(chosenStorage);
|
|
}
|
|
}
|