|
@@ -157,6 +157,7 @@ public class MiniDFSCluster {
|
|
private boolean checkExitOnShutdown = true;
|
|
private boolean checkExitOnShutdown = true;
|
|
private boolean checkDataNodeAddrConfig = false;
|
|
private boolean checkDataNodeAddrConfig = false;
|
|
private boolean checkDataNodeHostConfig = false;
|
|
private boolean checkDataNodeHostConfig = false;
|
|
|
|
+ private Configuration[] dnConfOverlays;
|
|
|
|
|
|
public Builder(Configuration conf) {
|
|
public Builder(Configuration conf) {
|
|
this.conf = conf;
|
|
this.conf = conf;
|
|
@@ -333,6 +334,19 @@ public class MiniDFSCluster {
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Default: null
|
|
|
|
+ *
|
|
|
|
+ * An array of {@link Configuration} objects that will overlay the
|
|
|
|
+ * global MiniDFSCluster Configuration for the corresponding DataNode.
|
|
|
|
+ *
|
|
|
|
+ * Useful for setting specific per-DataNode configuration parameters.
|
|
|
|
+ */
|
|
|
|
+ public Builder dataNodeConfOverlays(Configuration[] dnConfOverlays) {
|
|
|
|
+ this.dnConfOverlays = dnConfOverlays;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Construct the actual MiniDFSCluster
|
|
* Construct the actual MiniDFSCluster
|
|
*/
|
|
*/
|
|
@@ -375,7 +389,8 @@ public class MiniDFSCluster {
|
|
builder.nnTopology,
|
|
builder.nnTopology,
|
|
builder.checkExitOnShutdown,
|
|
builder.checkExitOnShutdown,
|
|
builder.checkDataNodeAddrConfig,
|
|
builder.checkDataNodeAddrConfig,
|
|
- builder.checkDataNodeHostConfig);
|
|
|
|
|
|
+ builder.checkDataNodeHostConfig,
|
|
|
|
+ builder.dnConfOverlays);
|
|
}
|
|
}
|
|
|
|
|
|
public class DataNodeProperties {
|
|
public class DataNodeProperties {
|
|
@@ -625,7 +640,7 @@ public class MiniDFSCluster {
|
|
manageNameDfsDirs, true, manageDataDfsDirs, manageDataDfsDirs,
|
|
manageNameDfsDirs, true, manageDataDfsDirs, manageDataDfsDirs,
|
|
operation, null, racks, hosts,
|
|
operation, null, racks, hosts,
|
|
simulatedCapacities, null, true, false,
|
|
simulatedCapacities, null, true, false,
|
|
- MiniDFSNNTopology.simpleSingleNN(nameNodePort, 0), true, false, false);
|
|
|
|
|
|
+ MiniDFSNNTopology.simpleSingleNN(nameNodePort, 0), true, false, false, null);
|
|
}
|
|
}
|
|
|
|
|
|
private void initMiniDFSCluster(
|
|
private void initMiniDFSCluster(
|
|
@@ -638,7 +653,8 @@ public class MiniDFSCluster {
|
|
boolean waitSafeMode, boolean setupHostsFile,
|
|
boolean waitSafeMode, boolean setupHostsFile,
|
|
MiniDFSNNTopology nnTopology, boolean checkExitOnShutdown,
|
|
MiniDFSNNTopology nnTopology, boolean checkExitOnShutdown,
|
|
boolean checkDataNodeAddrConfig,
|
|
boolean checkDataNodeAddrConfig,
|
|
- boolean checkDataNodeHostConfig)
|
|
|
|
|
|
+ boolean checkDataNodeHostConfig,
|
|
|
|
+ Configuration[] dnConfOverlays)
|
|
throws IOException {
|
|
throws IOException {
|
|
ExitUtil.disableSystemExit();
|
|
ExitUtil.disableSystemExit();
|
|
|
|
|
|
@@ -703,7 +719,7 @@ public class MiniDFSCluster {
|
|
startDataNodes(conf, numDataNodes, storageType, manageDataDfsDirs,
|
|
startDataNodes(conf, numDataNodes, storageType, manageDataDfsDirs,
|
|
dnStartOpt != null ? dnStartOpt : startOpt,
|
|
dnStartOpt != null ? dnStartOpt : startOpt,
|
|
racks, hosts, simulatedCapacities, setupHostsFile,
|
|
racks, hosts, simulatedCapacities, setupHostsFile,
|
|
- checkDataNodeAddrConfig, checkDataNodeHostConfig);
|
|
|
|
|
|
+ checkDataNodeAddrConfig, checkDataNodeHostConfig, dnConfOverlays);
|
|
waitClusterUp();
|
|
waitClusterUp();
|
|
//make sure ProxyUsers uses the latest conf
|
|
//make sure ProxyUsers uses the latest conf
|
|
ProxyUsers.refreshSuperUserGroupsConfiguration(conf);
|
|
ProxyUsers.refreshSuperUserGroupsConfiguration(conf);
|
|
@@ -1110,7 +1126,7 @@ public class MiniDFSCluster {
|
|
long[] simulatedCapacities,
|
|
long[] simulatedCapacities,
|
|
boolean setupHostsFile) throws IOException {
|
|
boolean setupHostsFile) throws IOException {
|
|
startDataNodes(conf, numDataNodes, StorageType.DEFAULT, manageDfsDirs, operation, racks, hosts,
|
|
startDataNodes(conf, numDataNodes, StorageType.DEFAULT, manageDfsDirs, operation, racks, hosts,
|
|
- simulatedCapacities, setupHostsFile, false, false);
|
|
|
|
|
|
+ simulatedCapacities, setupHostsFile, false, false, null);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1124,7 +1140,7 @@ public class MiniDFSCluster {
|
|
boolean setupHostsFile,
|
|
boolean setupHostsFile,
|
|
boolean checkDataNodeAddrConfig) throws IOException {
|
|
boolean checkDataNodeAddrConfig) throws IOException {
|
|
startDataNodes(conf, numDataNodes, StorageType.DEFAULT, manageDfsDirs, operation, racks, hosts,
|
|
startDataNodes(conf, numDataNodes, StorageType.DEFAULT, manageDfsDirs, operation, racks, hosts,
|
|
- simulatedCapacities, setupHostsFile, checkDataNodeAddrConfig, false);
|
|
|
|
|
|
+ simulatedCapacities, setupHostsFile, checkDataNodeAddrConfig, false, null);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1151,7 +1167,8 @@ public class MiniDFSCluster {
|
|
* @param setupHostsFile add new nodes to dfs hosts files
|
|
* @param setupHostsFile add new nodes to dfs hosts files
|
|
* @param checkDataNodeAddrConfig if true, only set DataNode port addresses if not already set in config
|
|
* @param checkDataNodeAddrConfig if true, only set DataNode port addresses if not already set in config
|
|
* @param checkDataNodeHostConfig if true, only set DataNode hostname key if not already set in config
|
|
* @param checkDataNodeHostConfig if true, only set DataNode hostname key if not already set in config
|
|
- *
|
|
|
|
|
|
+ * @param dnConfOverlays An array of {@link Configuration} objects that will overlay the
|
|
|
|
+ * global MiniDFSCluster Configuration for the corresponding DataNode.
|
|
* @throws IllegalStateException if NameNode has been shutdown
|
|
* @throws IllegalStateException if NameNode has been shutdown
|
|
*/
|
|
*/
|
|
public synchronized void startDataNodes(Configuration conf, int numDataNodes,
|
|
public synchronized void startDataNodes(Configuration conf, int numDataNodes,
|
|
@@ -1160,7 +1177,8 @@ public class MiniDFSCluster {
|
|
long[] simulatedCapacities,
|
|
long[] simulatedCapacities,
|
|
boolean setupHostsFile,
|
|
boolean setupHostsFile,
|
|
boolean checkDataNodeAddrConfig,
|
|
boolean checkDataNodeAddrConfig,
|
|
- boolean checkDataNodeHostConfig) throws IOException {
|
|
|
|
|
|
+ boolean checkDataNodeHostConfig,
|
|
|
|
+ Configuration[] dnConfOverlays) throws IOException {
|
|
if (operation == StartupOption.RECOVER) {
|
|
if (operation == StartupOption.RECOVER) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -1200,6 +1218,13 @@ public class MiniDFSCluster {
|
|
+ simulatedCapacities.length
|
|
+ simulatedCapacities.length
|
|
+ "] is less than the number of datanodes [" + numDataNodes + "].");
|
|
+ "] is less than the number of datanodes [" + numDataNodes + "].");
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (dnConfOverlays != null
|
|
|
|
+ && numDataNodes > dnConfOverlays.length) {
|
|
|
|
+ throw new IllegalArgumentException( "The length of dnConfOverlays ["
|
|
|
|
+ + dnConfOverlays.length
|
|
|
|
+ + "] is less than the number of datanodes [" + numDataNodes + "].");
|
|
|
|
+ }
|
|
|
|
|
|
String [] dnArgs = (operation == null ||
|
|
String [] dnArgs = (operation == null ||
|
|
operation != StartupOption.ROLLBACK) ?
|
|
operation != StartupOption.ROLLBACK) ?
|
|
@@ -1208,6 +1233,9 @@ public class MiniDFSCluster {
|
|
|
|
|
|
for (int i = curDatanodesNum; i < curDatanodesNum+numDataNodes; i++) {
|
|
for (int i = curDatanodesNum; i < curDatanodesNum+numDataNodes; i++) {
|
|
Configuration dnConf = new HdfsConfiguration(conf);
|
|
Configuration dnConf = new HdfsConfiguration(conf);
|
|
|
|
+ if (dnConfOverlays != null) {
|
|
|
|
+ dnConf.addResource(dnConfOverlays[i]);
|
|
|
|
+ }
|
|
// Set up datanode address
|
|
// Set up datanode address
|
|
setupDatanodeAddress(dnConf, setupHostsFile, checkDataNodeAddrConfig);
|
|
setupDatanodeAddress(dnConf, setupHostsFile, checkDataNodeAddrConfig);
|
|
if (manageDfsDirs) {
|
|
if (manageDfsDirs) {
|
|
@@ -2057,17 +2085,19 @@ public class MiniDFSCluster {
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* This method is valid only if the data nodes have simulated data
|
|
* This method is valid only if the data nodes have simulated data
|
|
* @param dataNodeIndex - data node i which to inject - the index is same as for getDataNodes()
|
|
* @param dataNodeIndex - data node i which to inject - the index is same as for getDataNodes()
|
|
* @param blocksToInject - the blocks
|
|
* @param blocksToInject - the blocks
|
|
|
|
+ * @param bpid - (optional) the block pool id to use for injecting blocks.
|
|
|
|
+ * If not supplied then it is queried from the in-process NameNode.
|
|
* @throws IOException
|
|
* @throws IOException
|
|
* if not simulatedFSDataset
|
|
* if not simulatedFSDataset
|
|
* if any of blocks already exist in the data node
|
|
* if any of blocks already exist in the data node
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
- public void injectBlocks(int dataNodeIndex, Iterable<Block> blocksToInject) throws IOException {
|
|
|
|
|
|
+ public void injectBlocks(int dataNodeIndex,
|
|
|
|
+ Iterable<Block> blocksToInject, String bpid) throws IOException {
|
|
if (dataNodeIndex < 0 || dataNodeIndex > dataNodes.size()) {
|
|
if (dataNodeIndex < 0 || dataNodeIndex > dataNodes.size()) {
|
|
throw new IndexOutOfBoundsException();
|
|
throw new IndexOutOfBoundsException();
|
|
}
|
|
}
|
|
@@ -2076,7 +2106,9 @@ public class MiniDFSCluster {
|
|
if (!(dataSet instanceof SimulatedFSDataset)) {
|
|
if (!(dataSet instanceof SimulatedFSDataset)) {
|
|
throw new IOException("injectBlocks is valid only for SimilatedFSDataset");
|
|
throw new IOException("injectBlocks is valid only for SimilatedFSDataset");
|
|
}
|
|
}
|
|
- String bpid = getNamesystem().getBlockPoolId();
|
|
|
|
|
|
+ if (bpid == null) {
|
|
|
|
+ bpid = getNamesystem().getBlockPoolId();
|
|
|
|
+ }
|
|
SimulatedFSDataset sdataset = (SimulatedFSDataset) dataSet;
|
|
SimulatedFSDataset sdataset = (SimulatedFSDataset) dataSet;
|
|
sdataset.injectBlocks(bpid, blocksToInject);
|
|
sdataset.injectBlocks(bpid, blocksToInject);
|
|
dataNodes.get(dataNodeIndex).datanode.scheduleAllBlockReport(0);
|
|
dataNodes.get(dataNodeIndex).datanode.scheduleAllBlockReport(0);
|
|
@@ -2101,25 +2133,6 @@ public class MiniDFSCluster {
|
|
dataNodes.get(dataNodeIndex).datanode.scheduleAllBlockReport(0);
|
|
dataNodes.get(dataNodeIndex).datanode.scheduleAllBlockReport(0);
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * This method is valid only if the data nodes have simulated data
|
|
|
|
- * @param blocksToInject - blocksToInject[] is indexed in the same order as the list
|
|
|
|
- * of datanodes returned by getDataNodes()
|
|
|
|
- * @throws IOException
|
|
|
|
- * if not simulatedFSDataset
|
|
|
|
- * if any of blocks already exist in the data nodes
|
|
|
|
- * Note the rest of the blocks are not injected.
|
|
|
|
- */
|
|
|
|
- public void injectBlocks(Iterable<Block>[] blocksToInject)
|
|
|
|
- throws IOException {
|
|
|
|
- if (blocksToInject.length > dataNodes.size()) {
|
|
|
|
- throw new IndexOutOfBoundsException();
|
|
|
|
- }
|
|
|
|
- for (int i = 0; i < blocksToInject.length; ++i) {
|
|
|
|
- injectBlocks(i, blocksToInject[i]);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Set the softLimit and hardLimit of client lease periods
|
|
* Set the softLimit and hardLimit of client lease periods
|
|
*/
|
|
*/
|
|
@@ -2166,11 +2179,13 @@ public class MiniDFSCluster {
|
|
* @return the base directory for this instance.
|
|
* @return the base directory for this instance.
|
|
*/
|
|
*/
|
|
protected String determineDfsBaseDir() {
|
|
protected String determineDfsBaseDir() {
|
|
- String dfsdir = conf.get(HDFS_MINIDFS_BASEDIR, null);
|
|
|
|
- if (dfsdir == null) {
|
|
|
|
- dfsdir = getBaseDirectory();
|
|
|
|
|
|
+ if (conf != null) {
|
|
|
|
+ final String dfsdir = conf.get(HDFS_MINIDFS_BASEDIR, null);
|
|
|
|
+ if (dfsdir != null) {
|
|
|
|
+ return dfsdir;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return dfsdir;
|
|
|
|
|
|
+ return getBaseDirectory();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|