Skip to content

Commit 1732312

Browse files
ChenSammixiaoyuyao
authored andcommitted
HDDS-1663. Add datanode to network topology cluster during node regis… (#937)
1 parent cf84881 commit 1732312

File tree

17 files changed

+573
-9
lines changed

17 files changed

+573
-9
lines changed

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/net/Node.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,23 @@ public interface Node {
3232
* exclude itself. In another words, its parent's full network location */
3333
String getNetworkLocation();
3434

35+
/**
36+
* Set this node's network location.
37+
* @param location it's network location
38+
*/
39+
void setNetworkLocation(String location);
40+
3541
/** @return this node's self name in network topology. This should be node's
3642
* IP or hostname.
3743
* */
3844
String getNetworkName();
3945

46+
/**
47+
* Set this node's name, can be hostname or Ipaddress.
48+
* @param name it's network name
49+
*/
50+
void setNetworkName(String name);
51+
4052
/** @return this node's full path in network topology. It's the concatenation
4153
* of location and name.
4254
* */

hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/net/NodeImpl.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
*/
2828
public class NodeImpl implements Node {
2929
// host:port#
30-
private final String name;
30+
private String name;
3131
// string representation of this node's location, such as /dc1/rack1
32-
private final String location;
32+
private String location;
3333
// location + "/" + name
34-
private final String path;
34+
private String path;
3535
// which level of the tree the node resides, start from 1 for root
3636
private int level;
3737
// node's parent
@@ -53,10 +53,7 @@ public NodeImpl(String name, String location, int cost) {
5353
}
5454
this.name = (name == null) ? ROOT : name;
5555
this.location = NetUtils.normalize(location);
56-
this.path = this.location.equals(PATH_SEPARATOR_STR) ?
57-
this.location + this.name :
58-
this.location + PATH_SEPARATOR_STR + this.name;
59-
56+
this.path = getPath();
6057
this.cost = cost;
6158
}
6259

@@ -84,13 +81,32 @@ public String getNetworkName() {
8481
return name;
8582
}
8683

84+
/**
85+
* Set this node's name, can be hostname or Ipaddress.
86+
* @param networkName it's network name
87+
*/
88+
public void setNetworkName(String networkName) {
89+
this.name = networkName;
90+
this.path = getPath();
91+
}
92+
8793
/**
8894
* @return this node's network location
8995
*/
9096
public String getNetworkLocation() {
9197
return location;
9298
}
9399

100+
/**
101+
* Set this node's network location.
102+
* @param networkLocation it's network location
103+
*/
104+
@Override
105+
public void setNetworkLocation(String networkLocation) {
106+
this.location = networkLocation;
107+
this.path = getPath();
108+
}
109+
94110
/**
95111
* @return this node's full path in network topology. It's the concatenation
96112
* of location and name.
@@ -197,4 +213,10 @@ public int hashCode() {
197213
public String toString() {
198214
return getNetworkFullPath();
199215
}
216+
217+
private String getPath() {
218+
return this.location.equals(PATH_SEPARATOR_STR) ?
219+
this.location + this.name :
220+
this.location + PATH_SEPARATOR_STR + this.name;
221+
}
200222
}

hadoop-hdds/server-scm/pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
145145
<testResource>
146146
<directory>${basedir}/../../hadoop-hdds/common/src/main/resources</directory>
147147
</testResource>
148+
<testResource>
149+
<directory>${basedir}/src/test/resources</directory>
150+
</testResource>
148151
</testResources>
149152
</build>
150153
</project>

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/NodeManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,13 @@ void processNodeReport(DatanodeDetails datanodeDetails,
171171
*/
172172
// TODO: We can give better name to this method!
173173
List<SCMCommand> getCommandQueue(UUID dnID);
174+
175+
/**
176+
* Given datanode host address, returns the DatanodeDetails for the
177+
* node.
178+
*
179+
* @param address node host address
180+
* @return the given datanode, or null if not found
181+
*/
182+
DatanodeDetails getNode(String address);
174183
}

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/SCMNodeManager.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import org.apache.hadoop.hdds.protocol.proto
2424
.StorageContainerDatanodeProtocolProtos.PipelineReportsProto;
2525
import org.apache.hadoop.hdds.scm.container.ContainerID;
26+
import org.apache.hadoop.hdds.scm.net.NetConstants;
27+
import org.apache.hadoop.hdds.scm.net.NetworkTopology;
28+
import org.apache.hadoop.hdds.scm.net.Node;
2629
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
2730
import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
2831
import org.apache.hadoop.hdds.scm.node.states.NodeAlreadyExistsException;
@@ -44,14 +47,19 @@
4447
.StorageContainerDatanodeProtocolProtos.StorageReportProto;
4548
import org.apache.hadoop.hdds.protocol.proto
4649
.StorageContainerDatanodeProtocolProtos.SCMVersionRequestProto;
50+
import org.apache.hadoop.hdfs.DFSConfigKeys;
4751
import org.apache.hadoop.ipc.Server;
4852
import org.apache.hadoop.metrics2.util.MBeans;
53+
import org.apache.hadoop.net.CachedDNSToSwitchMapping;
54+
import org.apache.hadoop.net.DNSToSwitchMapping;
55+
import org.apache.hadoop.net.TableMapping;
4956
import org.apache.hadoop.ozone.OzoneConsts;
5057
import org.apache.hadoop.ozone.protocol.VersionResponse;
5158
import org.apache.hadoop.ozone.protocol.commands.CommandForDatanode;
5259
import org.apache.hadoop.ozone.protocol.commands.RegisteredCommand;
5360
import org.apache.hadoop.ozone.protocol.commands.SCMCommand;
5461

62+
import org.apache.hadoop.util.ReflectionUtils;
5563
import org.slf4j.Logger;
5664
import org.slf4j.LoggerFactory;
5765

@@ -93,6 +101,9 @@ public class SCMNodeManager implements NodeManager {
93101
// Node manager MXBean
94102
private ObjectName nmInfoBean;
95103
private final StorageContainerManager scmManager;
104+
private final NetworkTopology clusterMap;
105+
private final DNSToSwitchMapping dnsToSwitchMapping;
106+
private final boolean useHostname;
96107

97108
/**
98109
* Constructs SCM machine Manager.
@@ -108,6 +119,18 @@ public SCMNodeManager(OzoneConfiguration conf, String clusterID,
108119
LOG.info("Entering startup safe mode.");
109120
registerMXBean();
110121
this.metrics = SCMNodeMetrics.create(this);
122+
this.clusterMap = scmManager.getClusterMap();
123+
Class<? extends DNSToSwitchMapping> dnsToSwitchMappingClass =
124+
conf.getClass(DFSConfigKeys.NET_TOPOLOGY_NODE_SWITCH_MAPPING_IMPL_KEY,
125+
TableMapping.class, DNSToSwitchMapping.class);
126+
DNSToSwitchMapping newInstance = ReflectionUtils.newInstance(
127+
dnsToSwitchMappingClass, conf);
128+
this.dnsToSwitchMapping =
129+
((newInstance instanceof CachedDNSToSwitchMapping) ? newInstance
130+
: new CachedDNSToSwitchMapping(newInstance));
131+
this.useHostname = conf.getBoolean(
132+
DFSConfigKeys.DFS_DATANODE_USE_DN_HOSTNAME,
133+
DFSConfigKeys.DFS_DATANODE_USE_DN_HOSTNAME_DEFAULT);
111134
}
112135

113136
private void registerMXBean() {
@@ -228,14 +251,27 @@ public RegisteredCommand register(
228251
datanodeDetails.setIpAddress(dnAddress.getHostAddress());
229252
}
230253
try {
254+
String location;
255+
if (useHostname) {
256+
datanodeDetails.setNetworkName(datanodeDetails.getHostName());
257+
location = nodeResolve(datanodeDetails.getHostName());
258+
} else {
259+
datanodeDetails.setNetworkName(datanodeDetails.getIpAddress());
260+
location = nodeResolve(datanodeDetails.getIpAddress());
261+
}
262+
if (location != null) {
263+
datanodeDetails.setNetworkLocation(location);
264+
}
231265
nodeStateManager.addNode(datanodeDetails);
266+
clusterMap.add(datanodeDetails);
232267
// Updating Node Report, as registration is successful
233268
processNodeReport(datanodeDetails, nodeReport);
234269
LOG.info("Registered Data node : {}", datanodeDetails);
235270
} catch (NodeAlreadyExistsException e) {
236271
LOG.trace("Datanode is already registered. Datanode: {}",
237272
datanodeDetails.toString());
238273
}
274+
239275
return RegisteredCommand.newBuilder().setErrorCode(ErrorCode.success)
240276
.setDatanodeUUID(datanodeDetails.getUuidString())
241277
.setClusterID(this.clusterID)
@@ -515,5 +551,36 @@ public List<SCMCommand> getCommandQueue(UUID dnID) {
515551
return commandQueue.getCommand(dnID);
516552
}
517553

554+
/**
555+
* Given datanode address or host name, returns the DatanodeDetails for the
556+
* node.
557+
*
558+
* @param address node host address
559+
* @return the given datanode, or null if not found
560+
*/
561+
@Override
562+
public DatanodeDetails getNode(String address) {
563+
Node node = null;
564+
String location = nodeResolve(address);
565+
if (location != null) {
566+
node = clusterMap.getNode(location + NetConstants.PATH_SEPARATOR_STR +
567+
address);
568+
}
569+
return node == null ? null : (DatanodeDetails)node;
570+
}
518571

572+
private String nodeResolve(String hostname) {
573+
List<String> hosts = new ArrayList<>(1);
574+
hosts.add(hostname);
575+
List<String> resolvedHosts = dnsToSwitchMapping.resolve(hosts);
576+
if (resolvedHosts != null && !resolvedHosts.isEmpty()) {
577+
String location = resolvedHosts.get(0);
578+
LOG.debug("Resolve datanode {} return location {}", hostname, location);
579+
return location;
580+
} else {
581+
LOG.error("Node {} Resolution failed. Please make sure that DNS table " +
582+
"mapping or configured mapping is functional.", hostname);
583+
return null;
584+
}
585+
}
519586
}

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,14 +372,15 @@ public StorageContainerManager(OzoneConfiguration conf,
372372
private void initializeSystemManagers(OzoneConfiguration conf,
373373
SCMConfigurator configurator)
374374
throws IOException {
375+
clusterMap = new NetworkTopologyImpl(conf);
376+
375377
if(configurator.getScmNodeManager() != null) {
376378
scmNodeManager = configurator.getScmNodeManager();
377379
} else {
378380
scmNodeManager = new SCMNodeManager(
379381
conf, scmStorageConfig.getClusterID(), this, eventQueue);
380382
}
381383

382-
clusterMap = new NetworkTopologyImpl(conf);
383384
ContainerPlacementPolicy containerPlacementPolicy =
384385
ContainerPlacementPolicyFactory.getPolicy(conf, scmNodeManager,
385386
clusterMap, true);
@@ -1067,4 +1068,12 @@ public Map<String, Integer> getContainerStateCount() {
10671068
public SCMMetadataStore getScmMetadataStore() {
10681069
return scmMetadataStore;
10691070
}
1071+
1072+
/**
1073+
* Returns the SCM network topology cluster.
1074+
* @return NetworkTopology
1075+
*/
1076+
public NetworkTopology getClusterMap() {
1077+
return this.clusterMap;
1078+
}
10701079
}

hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/TestUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public static DatanodeDetails getDatanodeDetails(
151151
*
152152
* @return DatanodeDetails
153153
*/
154-
private static DatanodeDetails createDatanodeDetails(String uuid,
154+
public static DatanodeDetails createDatanodeDetails(String uuid,
155155
String hostname, String ipAddress, String networkLocation) {
156156
DatanodeDetails.Port containerPort = DatanodeDetails.newPort(
157157
DatanodeDetails.Port.Name.STANDALONE, 0);

hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/MockNodeManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,11 @@ public List<SCMCommand> getCommandQueue(UUID dnID) {
451451
return null;
452452
}
453453

454+
@Override
455+
public DatanodeDetails getNode(String address) {
456+
return null;
457+
}
458+
454459
/**
455460
* A class to declare some values for the nodes so that our tests
456461
* won't fail.

0 commit comments

Comments
 (0)