From 6f699e8ea5d8a48c3daaf8dffa2292ce0524cfdb Mon Sep 17 00:00:00 2001 From: Arpit Agarwal Date: Thu, 22 Aug 2013 23:21:07 +0000 Subject: [PATCH] HDFS-5115. Make StorageID a UUID. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-2832@1516666 13f79535-47bb-0310-9956-ffa450edef68 --- .../blockmanagement/DatanodeManager.java | 37 ++--------------- .../hadoop/hdfs/server/datanode/DataNode.java | 41 ++----------------- .../hdfs/server/datanode/DataStorage.java | 7 ++-- .../hdfs/server/protocol/DatanodeStorage.java | 12 ++++++ .../server/datanode/SimulatedFSDataset.java | 15 +++---- .../server/datanode/TestBPOfferService.java | 2 +- .../datanode/TestSimulatedFSDataset.java | 2 +- 7 files changed, 29 insertions(+), 87 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java index 9d5024fb9b1..e9f4fdb636b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java @@ -23,13 +23,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.NavigableMap; -import java.util.TreeMap; +import java.util.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -54,15 +48,8 @@ import org.apache.hadoop.hdfs.server.namenode.HostFileManager.EntrySet; import org.apache.hadoop.hdfs.server.namenode.HostFileManager.MutableEntrySet; import org.apache.hadoop.hdfs.server.namenode.NameNode; import org.apache.hadoop.hdfs.server.namenode.Namesystem; -import org.apache.hadoop.hdfs.server.protocol.BalancerBandwidthCommand; -import org.apache.hadoop.hdfs.server.protocol.BlockCommand; -import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand; +import org.apache.hadoop.hdfs.server.protocol.*; import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock; -import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand; -import org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol; -import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration; -import org.apache.hadoop.hdfs.server.protocol.DisallowedDatanodeException; -import org.apache.hadoop.hdfs.server.protocol.RegisterCommand; import org.apache.hadoop.hdfs.util.CyclicIteration; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.ipc.Server; @@ -657,24 +644,6 @@ public class DatanodeManager { } } - /** - * Generate new storage ID. - * - * @return unique storage ID - * - * Note: that collisions are still possible if somebody will try - * to bring in a data storage from a different cluster. - */ - private String newStorageID() { - String newID = null; - while(newID == null) { - newID = "DS" + Integer.toString(DFSUtil.getRandom().nextInt()); - if (datanodeMap.get(newID) != null) - newID = null; - } - return newID; - } - /** * Register the given datanode with the namenode. NB: the given * registration is mutated and given back to the datanode. @@ -779,7 +748,7 @@ public class DatanodeManager { if ("".equals(nodeReg.getStorageID())) { // this data storage has never been registered // it is either empty or was created by pre-storageID version of DFS - nodeReg.setStorageID(newStorageID()); + nodeReg.setStorageID(DatanodeStorage.newStorageID()); if (NameNode.stateChangeLog.isDebugEnabled()) { NameNode.stateChangeLog.debug( "BLOCK* NameSystem.registerDatanode: " diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java index b86a5caebd1..acb9cf5688d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java @@ -67,15 +67,7 @@ import java.net.UnknownHostException; import java.nio.channels.ClosedByInterruptException; import java.nio.channels.SocketChannel; import java.security.PrivilegedExceptionAction; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.logging.Log; @@ -138,12 +130,8 @@ import org.apache.hadoop.hdfs.server.datanode.metrics.DataNodeMetrics; import org.apache.hadoop.hdfs.server.datanode.web.resources.DatanodeWebHdfsMethods; import org.apache.hadoop.hdfs.server.namenode.FileChecksumServlets; import org.apache.hadoop.hdfs.server.namenode.StreamFile; +import org.apache.hadoop.hdfs.server.protocol.*; import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock; -import org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol; -import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration; -import org.apache.hadoop.hdfs.server.protocol.InterDatanodeProtocol; -import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo; -import org.apache.hadoop.hdfs.server.protocol.ReplicaRecoveryInfo; import org.apache.hadoop.hdfs.web.WebHdfsFileSystem; import org.apache.hadoop.hdfs.web.resources.Param; import org.apache.hadoop.http.HttpServer; @@ -1041,30 +1029,7 @@ public class DataNode extends Configured public static void setNewStorageID(DatanodeID dnId) { LOG.info("Datanode is " + dnId); - dnId.setStorageID(createNewStorageId(dnId.getXferPort())); - } - - /** - * @return a unique storage ID of form "DS-randInt-ipaddr-port-timestamp" - */ - static String createNewStorageId(int port) { - // It is unlikely that we will create a non-unique storage ID - // for the following reasons: - // a) SecureRandom is a cryptographically strong random number generator - // b) IP addresses will likely differ on different hosts - // c) DataNode xfer ports will differ on the same host - // d) StorageIDs will likely be generated at different times (in ms) - // A conflict requires that all four conditions are violated. - // NB: The format of this string can be changed in the future without - // requiring that old SotrageIDs be updated. - String ip = "unknownIP"; - try { - ip = DNS.getDefaultIP("default"); - } catch (UnknownHostException ignored) { - LOG.warn("Could not find an IP address for the \"default\" inteface."); - } - int rand = DFSUtil.getSecureRandom().nextInt(Integer.MAX_VALUE); - return "DS-" + rand + "-" + ip + "-" + port + "-" + Time.now(); + dnId.setStorageID(DatanodeStorage.newStorageID()); } /** Ensure the authentication method is kerberos */ diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java index 9d31ffa673e..b04f46cedf1 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java @@ -50,6 +50,7 @@ import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.StartupOption; import org.apache.hadoop.hdfs.server.common.InconsistentFSStateException; import org.apache.hadoop.hdfs.server.common.Storage; import org.apache.hadoop.hdfs.server.common.StorageInfo; +import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage; import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.Daemon; @@ -106,11 +107,11 @@ public class DataStorage extends Storage { } /** Create an ID for this storage. */ - public synchronized void createStorageID(int datanodePort) { + public synchronized void createStorageID() { if (storageID != null && !storageID.isEmpty()) { return; } - storageID = DataNode.createNewStorageId(datanodePort); + storageID = DatanodeStorage.newStorageID(); } /** @@ -194,7 +195,7 @@ public class DataStorage extends Storage { } // make sure we have storage id set - if not - generate new one - createStorageID(datanode.getXferPort()); + createStorageID(); // 3. Update all storages. Some of them might have just been formatted. this.writeAll(); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/protocol/DatanodeStorage.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/protocol/DatanodeStorage.java index d8f1e945f5b..644b294f506 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/protocol/DatanodeStorage.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/protocol/DatanodeStorage.java @@ -19,6 +19,8 @@ package org.apache.hadoop.hdfs.server.protocol; import org.apache.hadoop.hdfs.StorageType; +import java.util.UUID; + /** * Class captures information of a storage in Datanode. */ @@ -64,4 +66,14 @@ public class DatanodeStorage { public StorageType getStorageType() { return storageType; } + + /** + * Generate new storage ID. The format of this string can be changed + * in the future without requiring that old SotrageIDs be updated. + * + * @return unique storage ID + */ + public static String newStorageID() { + return "DS-" + UUID.randomUUID(); + } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/SimulatedFSDataset.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/SimulatedFSDataset.java index 274e5a3a6bd..800a628a4e9 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/SimulatedFSDataset.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/SimulatedFSDataset.java @@ -22,11 +22,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; +import java.util.*; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; @@ -74,7 +70,7 @@ public class SimulatedFSDataset implements FsDatasetSpi { @Override public SimulatedFSDataset newInstance(DataNode datanode, DataStorage storage, Configuration conf) throws IOException { - return new SimulatedFSDataset(datanode, storage, conf); + return new SimulatedFSDataset(storage, conf); } @Override @@ -386,13 +382,12 @@ public class SimulatedFSDataset implements FsDatasetSpi { private final SimulatedStorage storage; private final String storageId; - public SimulatedFSDataset(DataNode datanode, DataStorage storage, - Configuration conf) { + public SimulatedFSDataset(DataStorage storage, Configuration conf) { if (storage != null) { - storage.createStorageID(datanode.getXferPort()); + storage.createStorageID(); this.storageId = storage.getStorageID(); } else { - this.storageId = "unknownStorageId" + new Random().nextInt(); + this.storageId = "unknownStorageId-" + UUID.randomUUID(); } registerMBean(storageId); this.storage = new SimulatedStorage( diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java index 42ea48230ee..db7a54b5c97 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestBPOfferService.java @@ -102,7 +102,7 @@ public class TestBPOfferService { .when(mockDn).getMetrics(); // Set up a simulated dataset with our fake BP - mockFSDataset = Mockito.spy(new SimulatedFSDataset(null, null, conf)); + mockFSDataset = Mockito.spy(new SimulatedFSDataset(null, conf)); mockFSDataset.addBlockPool(FAKE_BPID, conf); // Wire the dataset to the DN. diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestSimulatedFSDataset.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestSimulatedFSDataset.java index e8630091f65..d03e5ea0252 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestSimulatedFSDataset.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestSimulatedFSDataset.java @@ -311,7 +311,7 @@ public class TestSimulatedFSDataset { } private SimulatedFSDataset getSimulatedFSDataset() { - SimulatedFSDataset fsdataset = new SimulatedFSDataset(null, null, conf); + SimulatedFSDataset fsdataset = new SimulatedFSDataset(null, conf); fsdataset.addBlockPool(bpid, conf); return fsdataset; }