You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by xy...@apache.org on 2018/12/04 16:16:55 UTC
[04/50] [abbrv] hadoop git commit: HDFS-12946. Add a tool to check
rack configuration against EC policies. Contributed by Kitti Nanasi.
HDFS-12946. Add a tool to check rack configuration against EC policies. Contributed by Kitti Nanasi.
Signed-off-by: Wei-Chiu Chuang <we...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/dd5e7c6b
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/dd5e7c6b
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/dd5e7c6b
Branch: refs/heads/HDDS-4
Commit: dd5e7c6b7239a93f2391beaa11181e442a387db4
Parents: 3044b78
Author: Kitti Nanasi <kn...@cloudera.com>
Authored: Mon Dec 3 09:59:56 2018 -0800
Committer: Wei-Chiu Chuang <we...@apache.org>
Committed: Mon Dec 3 10:01:09 2018 -0800
----------------------------------------------------------------------
.../federation/metrics/NamenodeBeanMetrics.java | 5 +
.../server/blockmanagement/DatanodeManager.java | 7 +
.../hdfs/server/common/ECTopologyVerifier.java | 124 +++++++++++++++
.../namenode/ECTopologyVerifierResult.java | 45 ++++++
.../namenode/ErasureCodingPolicyManager.java | 9 ++
.../hdfs/server/namenode/FSNamesystem.java | 19 +++
.../hdfs/server/namenode/NameNodeMXBean.java | 7 +
.../org/apache/hadoop/hdfs/tools/ECAdmin.java | 51 +++++-
.../org/apache/hadoop/hdfs/DFSTestUtil.java | 35 +++++
.../hdfs/TestErasureCodingMultipleRacks.java | 18 +--
.../server/namenode/TestNameNodeMXBean.java | 19 +++
.../apache/hadoop/hdfs/tools/TestECAdmin.java | 157 +++++++++++++++++++
12 files changed, 479 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/NamenodeBeanMetrics.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/NamenodeBeanMetrics.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/NamenodeBeanMetrics.java
index e8ebf0d..0ca5f73 100644
--- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/NamenodeBeanMetrics.java
+++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/NamenodeBeanMetrics.java
@@ -706,4 +706,9 @@ public class NamenodeBeanMetrics
public int getNumEncryptionZones() {
return 0;
}
+
+ @Override
+ public String getVerifyECWithTopologyResult() {
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java
----------------------------------------------------------------------
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 430c0d4..8a3f57b 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
@@ -1253,6 +1253,13 @@ public class DatanodeManager {
return getDatanodeListForReport(DatanodeReportType.DEAD).size();
}
+ /** @return the number of datanodes. */
+ public int getNumOfDataNodes() {
+ synchronized (this) {
+ return datanodeMap.size();
+ }
+ }
+
/** @return list of datanodes where decommissioning is in progress. */
public List<DatanodeDescriptor> getDecommissioningNodes() {
// There is no need to take namesystem reader lock as
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/ECTopologyVerifier.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/ECTopologyVerifier.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/ECTopologyVerifier.java
new file mode 100644
index 0000000..3591b2d
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/ECTopologyVerifier.java
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.hadoop.hdfs.server.common;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
+import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicyInfo;
+import org.apache.hadoop.hdfs.server.namenode.ECTopologyVerifierResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class for verifying whether the cluster setup can support
+ * all enabled EC policies.
+ *
+ * Scenarios when the verification fails:
+ * 1. not enough data nodes compared to EC policy's highest data+parity number
+ * 2. not enough racks to satisfy BlockPlacementPolicyRackFaultTolerant
+ */
+@InterfaceAudience.Private
+public final class ECTopologyVerifier {
+
+ public static final Logger LOG =
+ LoggerFactory.getLogger(ECTopologyVerifier.class);
+
+ private ECTopologyVerifier() {}
+
+ /**
+ * Verifies whether the cluster setup can support all enabled EC policies.
+ *
+ * @param report list of data node descriptors for all data nodes
+ * @param policies all system and user defined erasure coding policies
+ * @return the status of the verification
+ */
+ public static ECTopologyVerifierResult getECTopologyVerifierResult(
+ final DatanodeInfo[] report, final ErasureCodingPolicyInfo[] policies) {
+ final int numOfRacks = getNumberOfRacks(report);
+ return getECTopologyVerifierResult(policies, numOfRacks, report.length);
+ }
+
+ /**
+ * Verifies whether the cluster setup can support all enabled EC policies.
+ *
+ * @param policies all system and user defined erasure coding policies
+ * @param numOfRacks number of racks
+ * @param numOfDataNodes number of data nodes
+ * @return the status of the verification
+ */
+ public static ECTopologyVerifierResult getECTopologyVerifierResult(
+ final ErasureCodingPolicyInfo[] policies, final int numOfRacks,
+ final int numOfDataNodes) {
+ int minDN = 0;
+ int minRack = 0;
+ for (ErasureCodingPolicyInfo policy: policies) {
+ if (policy.isEnabled()) {
+ final int policyDN =
+ policy.getPolicy().getNumDataUnits() + policy.getPolicy()
+ .getNumParityUnits();
+ minDN = Math.max(minDN, policyDN);
+ final int policyRack = (int) Math.ceil(
+ policyDN / (double) policy.getPolicy().getNumParityUnits());
+ minRack = Math.max(minRack, policyRack);
+ }
+ }
+ if (minDN == 0 || minRack == 0) {
+ String resultMessage = "No erasure coding policy is enabled.";
+ LOG.trace(resultMessage);
+ return new ECTopologyVerifierResult(true, resultMessage);
+ }
+ return verifyECWithTopology(minDN, minRack, numOfRacks, numOfDataNodes);
+ }
+
+ private static ECTopologyVerifierResult verifyECWithTopology(
+ final int minDN, final int minRack,
+ final int numOfRacks, final int numOfDataNodes) {
+ String resultMessage;
+ if (numOfDataNodes < minDN) {
+ resultMessage = "The number of DataNodes (" + numOfDataNodes
+ + ") is less than the minimum required number of DataNodes ("
+ + minDN + ") for enabled erasure coding policy.";
+ LOG.debug(resultMessage);
+ return new ECTopologyVerifierResult(false, resultMessage);
+ }
+
+ if (numOfRacks < minRack) {
+ resultMessage = "The number of racks (" + numOfRacks
+ + ") is less than the minimum required number of racks ("
+ + minRack + ") for enabled erasure coding policy.";
+ LOG.debug(resultMessage);
+ return new ECTopologyVerifierResult(false, resultMessage);
+ }
+ return new ECTopologyVerifierResult(true,
+ "The cluster setup can support all enabled EC policies");
+ }
+
+ private static int getNumberOfRacks(DatanodeInfo[] report) {
+ final Map<String, Integer> racks = new HashMap<>();
+ for (DatanodeInfo dni : report) {
+ Integer count = racks.get(dni.getNetworkLocation());
+ if (count == null) {
+ count = 0;
+ }
+ racks.put(dni.getNetworkLocation(), count + 1);
+ }
+ return racks.size();
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ECTopologyVerifierResult.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ECTopologyVerifierResult.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ECTopologyVerifierResult.java
new file mode 100644
index 0000000..4757eab
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ECTopologyVerifierResult.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdfs.server.namenode;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+
+/**
+ * Result of the verification whether the current cluster setup can
+ * support all enabled EC policies.
+ */
+@InterfaceAudience.Private
+public class ECTopologyVerifierResult {
+
+ private final String resultMessage;
+ private final boolean isSupported;
+
+ public ECTopologyVerifierResult(boolean isSupported,
+ String resultMessage) {
+ this.resultMessage = resultMessage;
+ this.isSupported = isSupported;
+ }
+
+ public String getResultMessage() {
+ return resultMessage;
+ }
+
+ public boolean isSupported() {
+ return isSupported;
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ErasureCodingPolicyManager.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ErasureCodingPolicyManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ErasureCodingPolicyManager.java
index 57fa958..fc673f7 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ErasureCodingPolicyManager.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ErasureCodingPolicyManager.java
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -204,6 +205,14 @@ public final class ErasureCodingPolicyManager {
.toArray(new ErasureCodingPolicyInfo[0]);
}
+ public ErasureCodingPolicyInfo[] getCopyOfPolicies() {
+ ErasureCodingPolicyInfo[] copy;
+ synchronized (this) {
+ copy = Arrays.copyOf(allPolicies, allPolicies.length);
+ }
+ return copy;
+ }
+
/**
* Get a {@link ErasureCodingPolicy} by policy ID, including system policy
* and user defined policy.
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
index 8b1cdf6..d85782f 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
@@ -102,6 +102,7 @@ import org.apache.hadoop.hdfs.protocol.OpenFileEntry;
import org.apache.hadoop.hdfs.protocol.ZoneReencryptionStatus;
import org.apache.hadoop.hdfs.protocol.SnapshotDiffReportListing;
import org.apache.hadoop.hdfs.protocol.SnapshotDiffReport;
+import org.apache.hadoop.hdfs.server.common.ECTopologyVerifier;
import org.apache.hadoop.hdfs.server.namenode.metrics.ReplicatedBlocksMBean;
import org.apache.hadoop.hdfs.server.protocol.SlowDiskReports;
import org.apache.hadoop.util.Time;
@@ -8167,6 +8168,24 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
.size();
}
+ @Override // NameNodeMXBean
+ public String getVerifyECWithTopologyResult() {
+ int numOfDataNodes = getBlockManager().getDatanodeManager()
+ .getNumOfDataNodes();
+ int numOfRacks = getBlockManager().getDatanodeManager()
+ .getNetworkTopology().getNumOfRacks();
+ ErasureCodingPolicyInfo[] ecPolicies =
+ getErasureCodingPolicyManager().getCopyOfPolicies();
+ ECTopologyVerifierResult result =
+ ECTopologyVerifier.getECTopologyVerifierResult(ecPolicies,
+ numOfRacks, numOfDataNodes);
+
+ Map<String, String> resultMap = new HashMap<String, String>();
+ resultMap.put("isSupported", Boolean.toString(result.isSupported()));
+ resultMap.put("resultMessage", result.getResultMessage());
+ return JSON.toString(resultMap);
+ }
+
// This method logs operatoinName without super user privilege.
// It should be called without holding FSN lock.
void checkSuperuserPrivilege(String operationName)
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeMXBean.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeMXBean.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeMXBean.java
index 5c7bbbb..8bf0bcb 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeMXBean.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeMXBean.java
@@ -303,4 +303,11 @@ public interface NameNodeMXBean {
*/
String getNameDirSize();
+ /**
+ * Verifies whether the cluster setup can support all enabled EC policies.
+ *
+ * @return the result of the verification
+ */
+ String getVerifyECWithTopologyResult();
+
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/ECAdmin.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/ECAdmin.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/ECAdmin.java
index 5f8626e..d63d9dd 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/ECAdmin.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/ECAdmin.java
@@ -24,9 +24,13 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.protocol.AddErasureCodingPolicyResponse;
+import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicy;
import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicyInfo;
+import org.apache.hadoop.hdfs.protocol.HdfsConstants;
import org.apache.hadoop.hdfs.protocol.NoECPolicySetException;
+import org.apache.hadoop.hdfs.server.common.ECTopologyVerifier;
+import org.apache.hadoop.hdfs.server.namenode.ECTopologyVerifierResult;
import org.apache.hadoop.hdfs.util.ECPolicyLoader;
import org.apache.hadoop.io.erasurecode.ErasureCodeConstants;
import org.apache.hadoop.tools.TableListing;
@@ -588,6 +592,50 @@ public class ECAdmin extends Configured implements Tool {
}
}
+ /**
+ * Command to verify the cluster setup can support all enabled EC policies.
+ */
+ private static class VerifyClusterSetupCommand
+ implements AdminHelper.Command {
+ @Override
+ public String getName() {
+ return "-verifyClusterSetup";
+ }
+
+ @Override
+ public String getShortUsage() {
+ return "[" + getName() + "]\n";
+ }
+
+ @Override
+ public String getLongUsage() {
+ return getShortUsage() + "\n"
+ + "Verify the cluster setup can support all enabled erasure coding"
+ + " policies.\n";
+ }
+
+ @Override
+ public int run(Configuration conf, List<String> args) throws IOException {
+ if (args.size() > 0) {
+ System.err.println(getName() + ": Too many arguments");
+ return 1;
+ }
+ final DistributedFileSystem dfs = AdminHelper.getDFS(conf);
+ final ErasureCodingPolicyInfo[] policies =
+ dfs.getClient().getNamenode().getErasureCodingPolicies();
+ final DatanodeInfo[] report = dfs.getClient().getNamenode()
+ .getDatanodeReport(HdfsConstants.DatanodeReportType.ALL);
+
+ ECTopologyVerifierResult result = ECTopologyVerifier
+ .getECTopologyVerifierResult(report, policies);
+ System.out.println(result.getResultMessage());
+ if (result.isSupported()) {
+ return 0;
+ }
+ return 2;
+ }
+ }
+
private static final AdminHelper.Command[] COMMANDS = {
new ListECPoliciesCommand(),
new AddECPoliciesCommand(),
@@ -597,6 +645,7 @@ public class ECAdmin extends Configured implements Tool {
new UnsetECPolicyCommand(),
new ListECCodecsCommand(),
new EnableECPolicyCommand(),
- new DisableECPolicyCommand()
+ new DisableECPolicyCommand(),
+ new VerifyClusterSetupCommand()
};
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/DFSTestUtil.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/DFSTestUtil.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/DFSTestUtil.java
index 9465b31..97609fb 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/DFSTestUtil.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/DFSTestUtil.java
@@ -2399,6 +2399,41 @@ public class DFSTestUtil {
}
/**
+ * Setup cluster with desired number of DN, racks, and specified number of
+ * rack that only has 1 DN. Other racks will be evenly setup with the number
+ * of DNs.
+ *
+ * @param conf the conf object to start the cluster.
+ * @param numDatanodes number of total Datanodes.
+ * @param numRacks number of total racks
+ * @param numSingleDnRacks number of racks that only has 1 DN
+ * @throws Exception
+ */
+ public static MiniDFSCluster setupCluster(final Configuration conf,
+ final int numDatanodes,
+ final int numRacks,
+ final int numSingleDnRacks)
+ throws Exception {
+ assert numDatanodes > numRacks;
+ assert numRacks > numSingleDnRacks;
+ assert numSingleDnRacks >= 0;
+ final String[] racks = new String[numDatanodes];
+ for (int i = 0; i < numSingleDnRacks; i++) {
+ racks[i] = "/rack" + i;
+ }
+ for (int i = numSingleDnRacks; i < numDatanodes; i++) {
+ racks[i] =
+ "/rack" + (numSingleDnRacks + (i % (numRacks - numSingleDnRacks)));
+ }
+ MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf)
+ .numDataNodes(numDatanodes)
+ .racks(racks)
+ .build();
+ cluster.waitActive();
+ return cluster;
+ }
+
+ /**
* Check the correctness of the snapshotDiff report.
* Make sure all items in the passed entries are in the snapshotDiff
* report.
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingMultipleRacks.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingMultipleRacks.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingMultipleRacks.java
index 3e87253..e47cbf0 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingMultipleRacks.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingMultipleRacks.java
@@ -92,23 +92,9 @@ public class TestErasureCodingMultipleRacks {
*/
public void setupCluster(final int numDatanodes, final int numRacks,
final int numSingleDnRacks) throws Exception {
- assert numDatanodes > numRacks;
- assert numRacks > numSingleDnRacks;
- assert numSingleDnRacks >= 0;
- final String[] racks = new String[numDatanodes];
- for (int i = 0; i < numSingleDnRacks; i++) {
- racks[i] = "/rack" + i;
- }
- for (int i = numSingleDnRacks; i < numDatanodes; i++) {
- racks[i] =
- "/rack" + (numSingleDnRacks + (i % (numRacks - numSingleDnRacks)));
- }
- cluster = new MiniDFSCluster.Builder(conf)
- .numDataNodes(numDatanodes)
- .racks(racks)
- .build();
+ cluster = DFSTestUtil
+ .setupCluster(conf, numDatanodes, numRacks, numSingleDnRacks);
dfs = cluster.getFileSystem();
- cluster.waitActive();
dfs.setErasureCodingPolicy(new Path("/"), ecPolicy.getName());
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java
index 07a4945..99b1d2b 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java
@@ -1008,6 +1008,7 @@ public class TestNameNodeMXBean {
expectedTotalReplicatedBlocks, totalReplicaBlocks.longValue());
assertEquals("Unexpected total ec block groups!",
expectedTotalECBlockGroups, totalECBlockGroups.longValue());
+ verifyEcClusterSetupVerifyResult(mbs);
}
private String getEnabledEcPoliciesMetric() throws Exception {
@@ -1017,4 +1018,22 @@ public class TestNameNodeMXBean {
return (String) (mbs.getAttribute(mxbeanName,
"EnabledEcPolicies"));
}
+
+ private void verifyEcClusterSetupVerifyResult(MBeanServer mbs)
+ throws Exception{
+ ObjectName namenodeMXBeanName = new ObjectName(
+ "Hadoop:service=NameNode,name=NameNodeInfo");
+ String result = (String) mbs.getAttribute(namenodeMXBeanName,
+ "VerifyECWithTopologyResult");
+ ObjectMapper mapper = new ObjectMapper();
+ Map<String, String> resultMap = mapper.readValue(result, Map.class);
+ Boolean isSupported = Boolean.parseBoolean(resultMap.get("isSupported"));
+ String resultMessage = resultMap.get("resultMessage");
+
+ assertFalse("Test cluster does not support all enabled " +
+ "erasure coding policies.", isSupported);
+ assertTrue(resultMessage.contains("The number of racks"));
+ assertTrue(resultMessage.contains("is less than the minimum required " +
+ "number of racks"));
+ }
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/dd5e7c6b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/TestECAdmin.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/TestECAdmin.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/TestECAdmin.java
new file mode 100644
index 0000000..f9d0d40
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/TestECAdmin.java
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdfs.tools;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hdfs.DFSTestUtil;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.hadoop.hdfs.protocol.SystemErasureCodingPolicies;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests some ECAdmin scenarios that are hard to test from
+ * {@link org.apache.hadoop.cli.TestErasureCodingCLI}.
+ */
+public class TestECAdmin {
+ public static final Logger LOG = LoggerFactory.getLogger(TestECAdmin.class);
+ private Configuration conf = new Configuration();
+ private MiniDFSCluster cluster;
+ private ECAdmin admin = new ECAdmin(conf);
+
+ private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ private static final PrintStream OLD_OUT = System.out;
+
+ @Rule
+ public Timeout globalTimeout =
+ new Timeout(300000, TimeUnit.MILLISECONDS);
+
+ @Before
+ public void setup() throws Exception {
+ System.setOut(new PrintStream(out));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try {
+ System.out.flush();
+ System.err.flush();
+ out.reset();
+ } finally {
+ System.setOut(OLD_OUT);
+ }
+
+ if (cluster != null) {
+ cluster.shutdown();
+ cluster = null;
+ }
+ }
+
+ @Test
+ public void testRS63MinDN() throws Exception {
+ cluster = DFSTestUtil.setupCluster(conf, 6, 3, 0);
+ String[] args = {"-verifyClusterSetup"};
+ final int ret = admin.run(args);
+ LOG.info("Commend stdout: {}", out.toString());
+ assertEquals(2, ret);
+ assertTrue(out.toString()
+ .contains("less than the minimum required number of DataNodes"));
+ }
+
+ @Test
+ public void testRS104MinRacks() throws Exception {
+ cluster = DFSTestUtil.setupCluster(conf, 15, 3, 0);
+ cluster.getFileSystem().enableErasureCodingPolicy(
+ SystemErasureCodingPolicies
+ .getByID(SystemErasureCodingPolicies.RS_10_4_POLICY_ID).getName());
+ String[] args = {"-verifyClusterSetup"};
+ final int ret = admin.run(args);
+ LOG.info("Commend stdout: {}", out.toString());
+ assertEquals(2, ret);
+ assertTrue(out.toString()
+ .contains("less than the minimum required number of racks"));
+ }
+
+ @Test
+ public void testXOR21MinRacks() throws Exception {
+ cluster = DFSTestUtil.setupCluster(conf, 5, 2, 0);
+ cluster.getFileSystem().disableErasureCodingPolicy(
+ SystemErasureCodingPolicies
+ .getByID(SystemErasureCodingPolicies.RS_6_3_POLICY_ID).getName());
+ cluster.getFileSystem().enableErasureCodingPolicy(
+ SystemErasureCodingPolicies
+ .getByID(SystemErasureCodingPolicies.XOR_2_1_POLICY_ID).getName());
+ String[] args = {"-verifyClusterSetup"};
+ final int ret = admin.run(args);
+ LOG.info("Commend stdout: {}", out.toString());
+ assertEquals(2, ret);
+ assertTrue(out.toString()
+ .contains("less than the minimum required number of racks"));
+ }
+
+ @Test
+ public void testRS32MinRacks() throws Exception {
+ cluster = DFSTestUtil.setupCluster(conf, 5, 2, 0);
+ cluster.getFileSystem().disableErasureCodingPolicy(
+ SystemErasureCodingPolicies
+ .getByID(SystemErasureCodingPolicies.RS_6_3_POLICY_ID).getName());
+ cluster.getFileSystem().enableErasureCodingPolicy(
+ SystemErasureCodingPolicies
+ .getByID(SystemErasureCodingPolicies.RS_3_2_POLICY_ID).getName());
+ String[] args = {"-verifyClusterSetup"};
+ final int ret = admin.run(args);
+ LOG.info("Commend stdout: {}", out.toString());
+ assertEquals(2, ret);
+ assertTrue(out.toString()
+ .contains("less than the minimum required number of racks"));
+ }
+
+ @Test
+ public void testRS63Good() throws Exception {
+ cluster = DFSTestUtil.setupCluster(conf, 9, 3, 0);
+ String[] args = {"-verifyClusterSetup"};
+ final int ret = admin.run(args);
+ LOG.info("Commend stdout: {}", out.toString());
+ assertEquals(0, ret);
+ }
+
+ @Test
+ public void testNoECEnabled() throws Exception {
+ cluster = DFSTestUtil.setupCluster(conf, 9, 3, 0);
+ cluster.getFileSystem().disableErasureCodingPolicy(
+ SystemErasureCodingPolicies
+ .getByID(SystemErasureCodingPolicies.RS_6_3_POLICY_ID).getName());
+ String[] args = {"-verifyClusterSetup"};
+ final int ret = admin.run(args);
+ LOG.info("Commend stdout: {}", out.toString());
+ assertEquals(0, ret);
+ assertTrue(out.toString().contains("No erasure coding policy is enabled"));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org