HDFS-15748. RBF: Move the router related part from hadoop-federation-balance module to hadoop-hdfs-rbf. Contributed by Jinglun.
This commit is contained in:
parent
66ee0a6df0
commit
77299ae992
|
@ -47,6 +47,7 @@ function hadoop_usage
|
||||||
hadoop_add_subcommand "trace" client "view and modify Hadoop tracing settings"
|
hadoop_add_subcommand "trace" client "view and modify Hadoop tracing settings"
|
||||||
hadoop_add_subcommand "version" client "print the version"
|
hadoop_add_subcommand "version" client "print the version"
|
||||||
hadoop_add_subcommand "kdiag" client "Diagnose Kerberos Problems"
|
hadoop_add_subcommand "kdiag" client "Diagnose Kerberos Problems"
|
||||||
|
hadoop_add_subcommand "rbfbalance" client "move directories and files across router-based federation namespaces"
|
||||||
hadoop_generate_usage "${HADOOP_SHELL_EXECNAME}" true
|
hadoop_generate_usage "${HADOOP_SHELL_EXECNAME}" true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +172,11 @@ function hadoopcmd_case
|
||||||
version)
|
version)
|
||||||
HADOOP_CLASSNAME=org.apache.hadoop.util.VersionInfo
|
HADOOP_CLASSNAME=org.apache.hadoop.util.VersionInfo
|
||||||
;;
|
;;
|
||||||
|
rbfbalance)
|
||||||
|
HADOOP_CLASSNAME=org.apache.hadoop.hdfs.rbfbalance.RouterFedBalance
|
||||||
|
hadoop_add_to_classpath_tools hadoop-federation-balance
|
||||||
|
hadoop_add_to_classpath_tools hadoop-distcp
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
HADOOP_CLASSNAME="${subcmd}"
|
HADOOP_CLASSNAME="${subcmd}"
|
||||||
if ! hadoop_validate_classname "${HADOOP_CLASSNAME}"; then
|
if ! hadoop_validate_classname "${HADOOP_CLASSNAME}"; then
|
||||||
|
|
|
@ -69,6 +69,11 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<artifactId>hadoop-hdfs-client</artifactId>
|
<artifactId>hadoop-hdfs-client</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.hadoop</groupId>
|
||||||
|
<artifactId>hadoop-federation-balance</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
@ -85,6 +90,12 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.hadoop</groupId>
|
||||||
|
<artifactId>hadoop-federation-balance</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<type>test-jar</type>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-annotations</artifactId>
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.tools.fedbalance;
|
package org.apache.hadoop.hdfs.rbfbalance;
|
||||||
|
|
||||||
import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting;
|
import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* 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.rbfbalance;
|
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.DistCpProcedure;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.FedBalanceContext;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy data through distcp in router-based federation cluster. It disables
|
||||||
|
* write by setting mount entry readonly.
|
||||||
|
*/
|
||||||
|
public class RouterDistCpProcedure extends DistCpProcedure {
|
||||||
|
|
||||||
|
public RouterDistCpProcedure() {}
|
||||||
|
|
||||||
|
public RouterDistCpProcedure(String name, String nextProcedure,
|
||||||
|
long delayDuration, FedBalanceContext context) throws IOException {
|
||||||
|
super(name, nextProcedure, delayDuration, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable write by making the mount entry readonly.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void disableWrite(FedBalanceContext context) throws IOException {
|
||||||
|
Configuration conf = context.getConf();
|
||||||
|
String mount = context.getMount();
|
||||||
|
MountTableProcedure.disableWrite(mount, conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable write.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void enableWrite() throws IOException {
|
||||||
|
// do nothing.
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,383 @@
|
||||||
|
/**
|
||||||
|
* 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.rbfbalance;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
|
import org.apache.commons.cli.GnuParser;
|
||||||
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.conf.Configured;
|
||||||
|
import org.apache.hadoop.fs.Path;
|
||||||
|
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager;
|
||||||
|
import org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys;
|
||||||
|
import org.apache.hadoop.hdfs.server.federation.router.RouterClient;
|
||||||
|
import org.apache.hadoop.hdfs.server.federation.store.records.MountTable;
|
||||||
|
import org.apache.hadoop.net.NetUtils;
|
||||||
|
import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.FedBalanceConfigs;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.FedBalanceConfigs.TrashOption;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.procedure.BalanceJob;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.procedure.BalanceProcedure;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.procedure.BalanceProcedureScheduler;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.TrashProcedure;
|
||||||
|
import org.apache.hadoop.tools.fedbalance.FedBalanceContext;
|
||||||
|
import org.apache.hadoop.util.Tool;
|
||||||
|
import org.apache.hadoop.util.ToolRunner;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalance.FED_BALANCE_DEFAULT_XML;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalance.FED_BALANCE_SITE_XML;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.CLI_OPTIONS;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.FORCE_CLOSE_OPEN;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.MAP;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.BANDWIDTH;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.DELAY_DURATION;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.DIFF_THRESHOLD;
|
||||||
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.TRASH;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Balance data in router-based federation cluster. From src sub-namespace to
|
||||||
|
* dst sub-namespace with distcp.
|
||||||
|
*
|
||||||
|
* 1. Move data from the source path to the destination path with distcp.
|
||||||
|
* 2. Update the the mount entry.
|
||||||
|
* 3. Delete the source path to trash.
|
||||||
|
*/
|
||||||
|
public class RouterFedBalance extends Configured implements Tool {
|
||||||
|
|
||||||
|
public static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(RouterFedBalance.class);
|
||||||
|
private static final String SUBMIT_COMMAND = "submit";
|
||||||
|
private static final String CONTINUE_COMMAND = "continue";
|
||||||
|
private static final String DISTCP_PROCEDURE = "distcp-procedure";
|
||||||
|
private static final String MOUNT_TABLE_PROCEDURE = "mount-table-procedure";
|
||||||
|
private static final String TRASH_PROCEDURE = "trash-procedure";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class helps building the balance job.
|
||||||
|
*/
|
||||||
|
private class Builder {
|
||||||
|
/* Force close all open files while there is no diff. */
|
||||||
|
private boolean forceCloseOpen = false;
|
||||||
|
/* Max number of concurrent maps to use for copy. */
|
||||||
|
private int map = 10;
|
||||||
|
/* Specify bandwidth per map in MB. */
|
||||||
|
private int bandwidth = 10;
|
||||||
|
/* Specify the trash behaviour of the source path. */
|
||||||
|
private FedBalanceConfigs.TrashOption trashOpt = TrashOption.TRASH;
|
||||||
|
/* Specify the duration(millie seconds) when the procedure needs retry. */
|
||||||
|
private long delayDuration = TimeUnit.SECONDS.toMillis(1);
|
||||||
|
/* Specify the threshold of diff entries. */
|
||||||
|
private int diffThreshold = 0;
|
||||||
|
/* The source input. This specifies the source path. */
|
||||||
|
private final String inputSrc;
|
||||||
|
/* The dst input. This specifies the dst path. */
|
||||||
|
private final String inputDst;
|
||||||
|
|
||||||
|
Builder(String inputSrc, String inputDst) {
|
||||||
|
this.inputSrc = inputSrc;
|
||||||
|
this.inputDst = inputDst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether force close all open files while there is no diff.
|
||||||
|
* @param value true if force close all the open files.
|
||||||
|
*/
|
||||||
|
public Builder setForceCloseOpen(boolean value) {
|
||||||
|
this.forceCloseOpen = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max number of concurrent maps to use for copy.
|
||||||
|
* @param value the map number of the distcp.
|
||||||
|
*/
|
||||||
|
public Builder setMap(int value) {
|
||||||
|
this.map = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify bandwidth per map in MB.
|
||||||
|
* @param value the bandwidth.
|
||||||
|
*/
|
||||||
|
public Builder setBandWidth(int value) {
|
||||||
|
this.bandwidth = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the trash behaviour of the source path.
|
||||||
|
* @param value the trash option.
|
||||||
|
*/
|
||||||
|
public Builder setTrashOpt(TrashOption value) {
|
||||||
|
this.trashOpt = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the duration(millie seconds) when the procedure needs retry.
|
||||||
|
* @param value the delay duration of the job.
|
||||||
|
*/
|
||||||
|
public Builder setDelayDuration(long value) {
|
||||||
|
this.delayDuration = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the threshold of diff entries.
|
||||||
|
* @param value the threshold of a fast distcp.
|
||||||
|
*/
|
||||||
|
public Builder setDiffThreshold(int value) {
|
||||||
|
this.diffThreshold = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the balance job.
|
||||||
|
*/
|
||||||
|
public BalanceJob build() throws IOException {
|
||||||
|
// Construct job context.
|
||||||
|
FedBalanceContext context;
|
||||||
|
Path dst = new Path(inputDst);
|
||||||
|
if (dst.toUri().getAuthority() == null) {
|
||||||
|
throw new IOException("The destination cluster must be specified.");
|
||||||
|
}
|
||||||
|
Path src = getSrcPath(inputSrc);
|
||||||
|
String mount = inputSrc;
|
||||||
|
context = new FedBalanceContext.Builder(src, dst, mount, getConf())
|
||||||
|
.setForceCloseOpenFiles(forceCloseOpen).setUseMountReadOnly(true)
|
||||||
|
.setMapNum(map).setBandwidthLimit(bandwidth).setTrash(trashOpt)
|
||||||
|
.setDelayDuration(delayDuration).setDiffThreshold(diffThreshold)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
LOG.info(context.toString());
|
||||||
|
// Construct the balance job.
|
||||||
|
BalanceJob.Builder<BalanceProcedure> builder = new BalanceJob.Builder<>();
|
||||||
|
RouterDistCpProcedure dcp =
|
||||||
|
new RouterDistCpProcedure(DISTCP_PROCEDURE, null, delayDuration,
|
||||||
|
context);
|
||||||
|
builder.nextProcedure(dcp);
|
||||||
|
MountTableProcedure mtp =
|
||||||
|
new MountTableProcedure(MOUNT_TABLE_PROCEDURE, null, delayDuration,
|
||||||
|
inputSrc, dst.toUri().getPath(), dst.toUri().getAuthority(),
|
||||||
|
getConf());
|
||||||
|
builder.nextProcedure(mtp);
|
||||||
|
TrashProcedure tp =
|
||||||
|
new TrashProcedure(TRASH_PROCEDURE, null, delayDuration, context);
|
||||||
|
builder.nextProcedure(tp);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouterFedBalance() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int run(String[] args) throws Exception {
|
||||||
|
CommandLineParser parser = new GnuParser();
|
||||||
|
CommandLine command = parser.parse(CLI_OPTIONS, args, true);
|
||||||
|
String[] leftOverArgs = command.getArgs();
|
||||||
|
if (leftOverArgs == null || leftOverArgs.length < 1) {
|
||||||
|
printUsage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
String cmd = leftOverArgs[0];
|
||||||
|
if (cmd.equals(SUBMIT_COMMAND)) {
|
||||||
|
if (leftOverArgs.length < 3) {
|
||||||
|
printUsage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
String inputSrc = leftOverArgs[1];
|
||||||
|
String inputDst = leftOverArgs[2];
|
||||||
|
return submit(command, inputSrc, inputDst);
|
||||||
|
} else if (cmd.equals(CONTINUE_COMMAND)) {
|
||||||
|
return continueJob();
|
||||||
|
} else {
|
||||||
|
printUsage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recover and continue the unfinished jobs.
|
||||||
|
*/
|
||||||
|
private int continueJob() throws InterruptedException {
|
||||||
|
BalanceProcedureScheduler scheduler =
|
||||||
|
new BalanceProcedureScheduler(getConf());
|
||||||
|
try {
|
||||||
|
scheduler.init(true);
|
||||||
|
while (true) {
|
||||||
|
Collection<BalanceJob> jobs = scheduler.getAllJobs();
|
||||||
|
int unfinished = 0;
|
||||||
|
for (BalanceJob job : jobs) {
|
||||||
|
if (!job.isJobDone()) {
|
||||||
|
unfinished++;
|
||||||
|
}
|
||||||
|
LOG.info(job.toString());
|
||||||
|
}
|
||||||
|
if (unfinished == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.sleep(TimeUnit.SECONDS.toMillis(10));
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Continue balance job failed.", e);
|
||||||
|
return -1;
|
||||||
|
} finally {
|
||||||
|
scheduler.shutDown();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a ProcedureScheduler and submit the job.
|
||||||
|
*
|
||||||
|
* @param command the command options.
|
||||||
|
* @param inputSrc the source input. This specifies the source path.
|
||||||
|
* @param inputDst the dst input. This specifies the dst path.
|
||||||
|
*/
|
||||||
|
private int submit(CommandLine command, String inputSrc, String inputDst)
|
||||||
|
throws IOException {
|
||||||
|
Builder builder = new Builder(inputSrc, inputDst);
|
||||||
|
// parse options.
|
||||||
|
builder.setForceCloseOpen(command.hasOption(FORCE_CLOSE_OPEN.getOpt()));
|
||||||
|
if (command.hasOption(MAP.getOpt())) {
|
||||||
|
builder.setMap(Integer.parseInt(command.getOptionValue(MAP.getOpt())));
|
||||||
|
}
|
||||||
|
if (command.hasOption(BANDWIDTH.getOpt())) {
|
||||||
|
builder.setBandWidth(
|
||||||
|
Integer.parseInt(command.getOptionValue(BANDWIDTH.getOpt())));
|
||||||
|
}
|
||||||
|
if (command.hasOption(DELAY_DURATION.getOpt())) {
|
||||||
|
builder.setDelayDuration(
|
||||||
|
Long.parseLong(command.getOptionValue(DELAY_DURATION.getOpt())));
|
||||||
|
}
|
||||||
|
if (command.hasOption(DIFF_THRESHOLD.getOpt())) {
|
||||||
|
builder.setDiffThreshold(Integer.parseInt(
|
||||||
|
command.getOptionValue(DIFF_THRESHOLD.getOpt())));
|
||||||
|
}
|
||||||
|
if (command.hasOption(TRASH.getOpt())) {
|
||||||
|
String val = command.getOptionValue(TRASH.getOpt());
|
||||||
|
if (val.equalsIgnoreCase("skip")) {
|
||||||
|
builder.setTrashOpt(TrashOption.SKIP);
|
||||||
|
} else if (val.equalsIgnoreCase("trash")) {
|
||||||
|
builder.setTrashOpt(TrashOption.TRASH);
|
||||||
|
} else if (val.equalsIgnoreCase("delete")) {
|
||||||
|
builder.setTrashOpt(TrashOption.DELETE);
|
||||||
|
} else {
|
||||||
|
printUsage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit the job.
|
||||||
|
BalanceProcedureScheduler scheduler =
|
||||||
|
new BalanceProcedureScheduler(getConf());
|
||||||
|
scheduler.init(false);
|
||||||
|
try {
|
||||||
|
BalanceJob balanceJob = builder.build();
|
||||||
|
// Submit and wait until the job is done.
|
||||||
|
scheduler.submit(balanceJob);
|
||||||
|
scheduler.waitUntilDone(balanceJob);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Submit balance job failed.", e);
|
||||||
|
return -1;
|
||||||
|
} finally {
|
||||||
|
scheduler.shutDown();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get src uri from Router.
|
||||||
|
*/
|
||||||
|
private Path getSrcPath(String fedPath) throws IOException {
|
||||||
|
String address = getConf().getTrimmed(
|
||||||
|
RBFConfigKeys.DFS_ROUTER_ADMIN_ADDRESS_KEY,
|
||||||
|
RBFConfigKeys.DFS_ROUTER_ADMIN_ADDRESS_DEFAULT);
|
||||||
|
InetSocketAddress routerSocket = NetUtils.createSocketAddr(address);
|
||||||
|
RouterClient rClient = new RouterClient(routerSocket, getConf());
|
||||||
|
try {
|
||||||
|
MountTableManager mountTable = rClient.getMountTableManager();
|
||||||
|
MountTable entry = MountTableProcedure.getMountEntry(fedPath, mountTable);
|
||||||
|
if (entry == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"The mount point doesn't exist. path=" + fedPath);
|
||||||
|
} else if (entry.getDestinations().size() > 1) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"The mount point has more than one destination. path=" + fedPath);
|
||||||
|
} else {
|
||||||
|
String ns = entry.getDestinations().get(0).getNameserviceId();
|
||||||
|
String path = entry.getDestinations().get(0).getDest();
|
||||||
|
return new Path("hdfs://" + ns + path);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
rClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printUsage() {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp(
|
||||||
|
"rbfbalance OPTIONS [submit|continue] <src> <target>\n\nOPTIONS",
|
||||||
|
CLI_OPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads properties from hdfs-fedbalance-default.xml into configuration
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* @return Configuration which includes properties from
|
||||||
|
* hdfs-fedbalance-default.xml and hdfs-fedbalance-site.xml
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
static Configuration getDefaultConf() {
|
||||||
|
Configuration config = new Configuration();
|
||||||
|
config.addResource(FED_BALANCE_DEFAULT_XML);
|
||||||
|
config.addResource(FED_BALANCE_SITE_XML);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function of the RouterFedBalance program. Parses the input arguments
|
||||||
|
* and invokes the RouterFedBalance::run() method, via the ToolRunner.
|
||||||
|
* @param argv Command-line arguments sent to RouterFedBalance.
|
||||||
|
*/
|
||||||
|
public static void main(String[] argv) {
|
||||||
|
Configuration conf = getDefaultConf();
|
||||||
|
RouterFedBalance fedBalance = new RouterFedBalance();
|
||||||
|
fedBalance.setConf(conf);
|
||||||
|
int exitCode;
|
||||||
|
try {
|
||||||
|
exitCode = ToolRunner.run(fedBalance, argv);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warn("Couldn't complete RouterFedBalance operation.", e);
|
||||||
|
exitCode = -1;
|
||||||
|
}
|
||||||
|
System.exit(exitCode);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FedBalance is a tool for balancing data across federation clusters.
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Public
|
||||||
|
package org.apache.hadoop.hdfs.rbfbalance;
|
||||||
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
@ -15,7 +15,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.tools.fedbalance;
|
package org.apache.hadoop.hdfs.rbfbalance;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
@ -103,17 +103,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.hadoop</groupId>
|
|
||||||
<artifactId>hadoop-hdfs-rbf</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.hadoop</groupId>
|
|
||||||
<artifactId>hadoop-hdfs-rbf</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
<type>test-jar</type>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
|
|
|
@ -155,7 +155,7 @@ public class DistCpProcedure extends BalanceProcedure {
|
||||||
diffDistCp();
|
diffDistCp();
|
||||||
return false;
|
return false;
|
||||||
case DISABLE_WRITE:
|
case DISABLE_WRITE:
|
||||||
disableWrite();
|
disableWrite(context);
|
||||||
return false;
|
return false;
|
||||||
case FINAL_DISTCP:
|
case FINAL_DISTCP:
|
||||||
finalDistCp();
|
finalDistCp();
|
||||||
|
@ -238,23 +238,28 @@ public class DistCpProcedure extends BalanceProcedure {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable write either by making the mount entry readonly or cancelling the
|
* Disable write by cancelling the execute permission of the source path.
|
||||||
* execute permission of the source path.
|
* TODO: Disable the super user from writing.
|
||||||
|
* @param fbcontext the context.
|
||||||
|
* @throws IOException if can't disable write.
|
||||||
*/
|
*/
|
||||||
void disableWrite() throws IOException {
|
protected void disableWrite(FedBalanceContext fbcontext) throws IOException {
|
||||||
if (useMountReadOnly) {
|
// Save and cancel permission.
|
||||||
String mount = context.getMount();
|
FileStatus status = srcFs.getFileStatus(src);
|
||||||
MountTableProcedure.disableWrite(mount, conf);
|
fPerm = status.getPermission();
|
||||||
} else {
|
acl = srcFs.getAclStatus(src);
|
||||||
// Save and cancel permission.
|
srcFs.setPermission(src, FsPermission.createImmutable((short) 0));
|
||||||
FileStatus status = srcFs.getFileStatus(src);
|
|
||||||
fPerm = status.getPermission();
|
|
||||||
acl = srcFs.getAclStatus(src);
|
|
||||||
srcFs.setPermission(src, FsPermission.createImmutable((short) 0));
|
|
||||||
}
|
|
||||||
updateStage(Stage.FINAL_DISTCP);
|
updateStage(Stage.FINAL_DISTCP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable write.
|
||||||
|
* @throws IOException if can't enable write.
|
||||||
|
*/
|
||||||
|
protected void enableWrite() throws IOException {
|
||||||
|
restorePermission();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable write by restoring the x permission.
|
* Enable write by restoring the x permission.
|
||||||
*/
|
*/
|
||||||
|
@ -297,9 +302,7 @@ public class DistCpProcedure extends BalanceProcedure {
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish() throws IOException {
|
void finish() throws IOException {
|
||||||
if (!useMountReadOnly) {
|
enableWrite();
|
||||||
restorePermission();
|
|
||||||
}
|
|
||||||
if (srcFs.exists(src)) {
|
if (srcFs.exists(src)) {
|
||||||
cleanupSnapshot(srcFs, src);
|
cleanupSnapshot(srcFs, src);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,24 +27,17 @@ import org.apache.hadoop.conf.Configured;
|
||||||
|
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.tools.fedbalance.procedure.BalanceProcedure;
|
import org.apache.hadoop.tools.fedbalance.procedure.BalanceProcedure;
|
||||||
import org.apache.hadoop.hdfs.server.federation.resolver.MountTableManager;
|
|
||||||
import org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys;
|
|
||||||
import org.apache.hadoop.hdfs.server.federation.router.RouterClient;
|
|
||||||
import org.apache.hadoop.hdfs.server.federation.store.records.MountTable;
|
|
||||||
import org.apache.hadoop.tools.fedbalance.procedure.BalanceJob;
|
import org.apache.hadoop.tools.fedbalance.procedure.BalanceJob;
|
||||||
import org.apache.hadoop.tools.fedbalance.procedure.BalanceProcedureScheduler;
|
import org.apache.hadoop.tools.fedbalance.procedure.BalanceProcedureScheduler;
|
||||||
import org.apache.hadoop.net.NetUtils;
|
|
||||||
import org.apache.hadoop.util.Tool;
|
import org.apache.hadoop.util.Tool;
|
||||||
import org.apache.hadoop.util.ToolRunner;
|
import org.apache.hadoop.util.ToolRunner;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.ROUTER;
|
|
||||||
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.FORCE_CLOSE_OPEN;
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.FORCE_CLOSE_OPEN;
|
||||||
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.MAP;
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.MAP;
|
||||||
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.BANDWIDTH;
|
import static org.apache.hadoop.tools.fedbalance.FedBalanceOptions.BANDWIDTH;
|
||||||
|
@ -58,8 +51,7 @@ import static org.apache.hadoop.tools.fedbalance.FedBalanceConfigs.TrashOption;
|
||||||
* Balance data from src cluster to dst cluster with distcp.
|
* Balance data from src cluster to dst cluster with distcp.
|
||||||
*
|
*
|
||||||
* 1. Move data from the source path to the destination path with distcp.
|
* 1. Move data from the source path to the destination path with distcp.
|
||||||
* 2. Update the the mount entry.
|
* 2. Delete the source path to trash.
|
||||||
* 3. Delete the source path to trash.
|
|
||||||
*/
|
*/
|
||||||
public class FedBalance extends Configured implements Tool {
|
public class FedBalance extends Configured implements Tool {
|
||||||
|
|
||||||
|
@ -69,19 +61,16 @@ public class FedBalance extends Configured implements Tool {
|
||||||
private static final String CONTINUE_COMMAND = "continue";
|
private static final String CONTINUE_COMMAND = "continue";
|
||||||
private static final String NO_MOUNT = "no-mount";
|
private static final String NO_MOUNT = "no-mount";
|
||||||
private static final String DISTCP_PROCEDURE = "distcp-procedure";
|
private static final String DISTCP_PROCEDURE = "distcp-procedure";
|
||||||
private static final String MOUNT_TABLE_PROCEDURE = "mount-table-procedure";
|
|
||||||
private static final String TRASH_PROCEDURE = "trash-procedure";
|
private static final String TRASH_PROCEDURE = "trash-procedure";
|
||||||
|
|
||||||
private static final String FED_BALANCE_DEFAULT_XML =
|
public static final String FED_BALANCE_DEFAULT_XML =
|
||||||
"hdfs-fedbalance-default.xml";
|
"hdfs-fedbalance-default.xml";
|
||||||
private static final String FED_BALANCE_SITE_XML = "hdfs-fedbalance-site.xml";
|
public static final String FED_BALANCE_SITE_XML = "hdfs-fedbalance-site.xml";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class helps building the balance job.
|
* This class helps building the balance job.
|
||||||
*/
|
*/
|
||||||
private class Builder {
|
private class Builder {
|
||||||
/* Balancing in an rbf cluster. */
|
|
||||||
private boolean routerCluster = false;
|
|
||||||
/* Force close all open files while there is no diff. */
|
/* Force close all open files while there is no diff. */
|
||||||
private boolean forceCloseOpen = false;
|
private boolean forceCloseOpen = false;
|
||||||
/* Max number of concurrent maps to use for copy. */
|
/* Max number of concurrent maps to use for copy. */
|
||||||
|
@ -104,15 +93,6 @@ public class FedBalance extends Configured implements Tool {
|
||||||
this.inputDst = inputDst;
|
this.inputDst = inputDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether balancing in an rbf cluster.
|
|
||||||
* @param value true if it's running in a router-based federation cluster.
|
|
||||||
*/
|
|
||||||
public Builder setRouterCluster(boolean value) {
|
|
||||||
this.routerCluster = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether force close all open files while there is no diff.
|
* Whether force close all open files while there is no diff.
|
||||||
* @param value true if force close all the open files.
|
* @param value true if force close all the open files.
|
||||||
|
@ -177,26 +157,14 @@ public class FedBalance extends Configured implements Tool {
|
||||||
if (dst.toUri().getAuthority() == null) {
|
if (dst.toUri().getAuthority() == null) {
|
||||||
throw new IOException("The destination cluster must be specified.");
|
throw new IOException("The destination cluster must be specified.");
|
||||||
}
|
}
|
||||||
if (routerCluster) { // router-based federation.
|
Path src = new Path(inputSrc);
|
||||||
Path src = getSrcPath(inputSrc);
|
if (src.toUri().getAuthority() == null) {
|
||||||
String mount = inputSrc;
|
throw new IOException("The source cluster must be specified.");
|
||||||
context = new FedBalanceContext.Builder(src, dst, mount, getConf())
|
|
||||||
.setForceCloseOpenFiles(forceCloseOpen)
|
|
||||||
.setUseMountReadOnly(routerCluster).setMapNum(map)
|
|
||||||
.setBandwidthLimit(bandwidth).setTrash(trashOpt)
|
|
||||||
.setDelayDuration(delayDuration)
|
|
||||||
.setDiffThreshold(diffThreshold).build();
|
|
||||||
} else { // normal federation cluster.
|
|
||||||
Path src = new Path(inputSrc);
|
|
||||||
if (src.toUri().getAuthority() == null) {
|
|
||||||
throw new IOException("The source cluster must be specified.");
|
|
||||||
}
|
|
||||||
context = new FedBalanceContext.Builder(src, dst, NO_MOUNT, getConf())
|
|
||||||
.setForceCloseOpenFiles(forceCloseOpen)
|
|
||||||
.setUseMountReadOnly(routerCluster).setMapNum(map)
|
|
||||||
.setBandwidthLimit(bandwidth).setTrash(trashOpt)
|
|
||||||
.setDiffThreshold(diffThreshold).build();
|
|
||||||
}
|
}
|
||||||
|
context = new FedBalanceContext.Builder(src, dst, NO_MOUNT, getConf())
|
||||||
|
.setForceCloseOpenFiles(forceCloseOpen).setUseMountReadOnly(false)
|
||||||
|
.setMapNum(map).setBandwidthLimit(bandwidth).setTrash(trashOpt)
|
||||||
|
.setDiffThreshold(diffThreshold).build();
|
||||||
|
|
||||||
LOG.info(context.toString());
|
LOG.info(context.toString());
|
||||||
// Construct the balance job.
|
// Construct the balance job.
|
||||||
|
@ -204,13 +172,6 @@ public class FedBalance extends Configured implements Tool {
|
||||||
DistCpProcedure dcp =
|
DistCpProcedure dcp =
|
||||||
new DistCpProcedure(DISTCP_PROCEDURE, null, delayDuration, context);
|
new DistCpProcedure(DISTCP_PROCEDURE, null, delayDuration, context);
|
||||||
builder.nextProcedure(dcp);
|
builder.nextProcedure(dcp);
|
||||||
if (routerCluster) {
|
|
||||||
MountTableProcedure mtp =
|
|
||||||
new MountTableProcedure(MOUNT_TABLE_PROCEDURE, null, delayDuration,
|
|
||||||
inputSrc, dst.toUri().getPath(), dst.toUri().getAuthority(),
|
|
||||||
getConf());
|
|
||||||
builder.nextProcedure(mtp);
|
|
||||||
}
|
|
||||||
TrashProcedure tp =
|
TrashProcedure tp =
|
||||||
new TrashProcedure(TRASH_PROCEDURE, null, delayDuration, context);
|
new TrashProcedure(TRASH_PROCEDURE, null, delayDuration, context);
|
||||||
builder.nextProcedure(tp);
|
builder.nextProcedure(tp);
|
||||||
|
@ -291,7 +252,6 @@ public class FedBalance extends Configured implements Tool {
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Builder builder = new Builder(inputSrc, inputDst);
|
Builder builder = new Builder(inputSrc, inputDst);
|
||||||
// parse options.
|
// parse options.
|
||||||
builder.setRouterCluster(command.hasOption(ROUTER.getOpt()));
|
|
||||||
builder.setForceCloseOpen(command.hasOption(FORCE_CLOSE_OPEN.getOpt()));
|
builder.setForceCloseOpen(command.hasOption(FORCE_CLOSE_OPEN.getOpt()));
|
||||||
if (command.hasOption(MAP.getOpt())) {
|
if (command.hasOption(MAP.getOpt())) {
|
||||||
builder.setMap(Integer.parseInt(command.getOptionValue(MAP.getOpt())));
|
builder.setMap(Integer.parseInt(command.getOptionValue(MAP.getOpt())));
|
||||||
|
@ -340,34 +300,6 @@ public class FedBalance extends Configured implements Tool {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get src uri from Router.
|
|
||||||
*/
|
|
||||||
private Path getSrcPath(String fedPath) throws IOException {
|
|
||||||
String address = getConf().getTrimmed(
|
|
||||||
RBFConfigKeys.DFS_ROUTER_ADMIN_ADDRESS_KEY,
|
|
||||||
RBFConfigKeys.DFS_ROUTER_ADMIN_ADDRESS_DEFAULT);
|
|
||||||
InetSocketAddress routerSocket = NetUtils.createSocketAddr(address);
|
|
||||||
RouterClient rClient = new RouterClient(routerSocket, getConf());
|
|
||||||
try {
|
|
||||||
MountTableManager mountTable = rClient.getMountTableManager();
|
|
||||||
MountTable entry = MountTableProcedure.getMountEntry(fedPath, mountTable);
|
|
||||||
if (entry == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"The mount point doesn't exist. path=" + fedPath);
|
|
||||||
} else if (entry.getDestinations().size() > 1) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"The mount point has more than one destination. path=" + fedPath);
|
|
||||||
} else {
|
|
||||||
String ns = entry.getDestinations().get(0).getNameserviceId();
|
|
||||||
String path = entry.getDestinations().get(0).getDest();
|
|
||||||
return new Path("hdfs://" + ns + path);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
rClient.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printUsage() {
|
private void printUsage() {
|
||||||
HelpFormatter formatter = new HelpFormatter();
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
formatter.printHelp(
|
formatter.printHelp(
|
||||||
|
|
|
@ -194,7 +194,7 @@ public class FedBalanceContext implements Writable {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Builder {
|
public static class Builder {
|
||||||
private final Path src;
|
private final Path src;
|
||||||
private final Path dst;
|
private final Path dst;
|
||||||
private final String mount;
|
private final String mount;
|
||||||
|
@ -215,7 +215,7 @@ public class FedBalanceContext implements Writable {
|
||||||
* @param mount the mount point to be balanced.
|
* @param mount the mount point to be balanced.
|
||||||
* @param conf the configuration.
|
* @param conf the configuration.
|
||||||
*/
|
*/
|
||||||
Builder(Path src, Path dst, String mount, Configuration conf) {
|
public Builder(Path src, Path dst, String mount, Configuration conf) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.dst = dst;
|
this.dst = dst;
|
||||||
this.mount = mount;
|
this.mount = mount;
|
||||||
|
@ -225,6 +225,7 @@ public class FedBalanceContext implements Writable {
|
||||||
/**
|
/**
|
||||||
* Force close open files.
|
* Force close open files.
|
||||||
* @param value true if force close all the open files.
|
* @param value true if force close all the open files.
|
||||||
|
* @return the builder.
|
||||||
*/
|
*/
|
||||||
public Builder setForceCloseOpenFiles(boolean value) {
|
public Builder setForceCloseOpenFiles(boolean value) {
|
||||||
this.forceCloseOpenFiles = value;
|
this.forceCloseOpenFiles = value;
|
||||||
|
@ -234,6 +235,7 @@ public class FedBalanceContext implements Writable {
|
||||||
/**
|
/**
|
||||||
* Use mount point readonly to disable write.
|
* Use mount point readonly to disable write.
|
||||||
* @param value true if disabling write by setting mount point readonly.
|
* @param value true if disabling write by setting mount point readonly.
|
||||||
|
* @return the builder.
|
||||||
*/
|
*/
|
||||||
public Builder setUseMountReadOnly(boolean value) {
|
public Builder setUseMountReadOnly(boolean value) {
|
||||||
this.useMountReadOnly = value;
|
this.useMountReadOnly = value;
|
||||||
|
@ -243,6 +245,7 @@ public class FedBalanceContext implements Writable {
|
||||||
/**
|
/**
|
||||||
* The map number of the distcp job.
|
* The map number of the distcp job.
|
||||||
* @param value the map number of the distcp.
|
* @param value the map number of the distcp.
|
||||||
|
* @return the builder.
|
||||||
*/
|
*/
|
||||||
public Builder setMapNum(int value) {
|
public Builder setMapNum(int value) {
|
||||||
this.mapNum = value;
|
this.mapNum = value;
|
||||||
|
@ -252,6 +255,7 @@ public class FedBalanceContext implements Writable {
|
||||||
/**
|
/**
|
||||||
* The bandwidth limit of the distcp job(MB).
|
* The bandwidth limit of the distcp job(MB).
|
||||||
* @param value the bandwidth.
|
* @param value the bandwidth.
|
||||||
|
* @return the builder.
|
||||||
*/
|
*/
|
||||||
public Builder setBandwidthLimit(int value) {
|
public Builder setBandwidthLimit(int value) {
|
||||||
this.bandwidthLimit = value;
|
this.bandwidthLimit = value;
|
||||||
|
@ -261,7 +265,8 @@ public class FedBalanceContext implements Writable {
|
||||||
/**
|
/**
|
||||||
* Specify the trash behaviour after all the data is sync to the target.
|
* Specify the trash behaviour after all the data is sync to the target.
|
||||||
* @param value the trash option.
|
* @param value the trash option.
|
||||||
* */
|
* @return the builder.
|
||||||
|
*/
|
||||||
public Builder setTrash(TrashOption value) {
|
public Builder setTrash(TrashOption value) {
|
||||||
this.trashOpt = value;
|
this.trashOpt = value;
|
||||||
return this;
|
return this;
|
||||||
|
@ -269,6 +274,8 @@ public class FedBalanceContext implements Writable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the delayed duration when the procedures need to retry.
|
* Specify the delayed duration when the procedures need to retry.
|
||||||
|
* @param value the delay duration.
|
||||||
|
* @return the builder.
|
||||||
*/
|
*/
|
||||||
public Builder setDelayDuration(long value) {
|
public Builder setDelayDuration(long value) {
|
||||||
this.delayDuration = value;
|
this.delayDuration = value;
|
||||||
|
@ -277,6 +284,8 @@ public class FedBalanceContext implements Writable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the threshold of diff entries.
|
* Specify the threshold of diff entries.
|
||||||
|
* @param value the diff threshold.
|
||||||
|
* @return the builder.
|
||||||
*/
|
*/
|
||||||
public Builder setDiffThreshold(int value) {
|
public Builder setDiffThreshold(int value) {
|
||||||
this.diffThreshold = value;
|
this.diffThreshold = value;
|
||||||
|
|
|
@ -30,43 +30,32 @@ public final class FedBalanceOptions {
|
||||||
*/
|
*/
|
||||||
private FedBalanceOptions() {}
|
private FedBalanceOptions() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Run in router-based federation mode.
|
|
||||||
*/
|
|
||||||
final static Option ROUTER = new Option("router", false,
|
|
||||||
"If this option is set then the command runs in router mode."
|
|
||||||
+ " The source path is taken as a mount point. It will disable write"
|
|
||||||
+ " by setting the mount point readonly. Otherwise the command works"
|
|
||||||
+ " in normal federation mode. The source path is taken as the full"
|
|
||||||
+ " path. It will disable write by cancelling all permissions of the"
|
|
||||||
+ " source path.");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, in DIFF_DISTCP stage it will force close all open files when
|
* If true, in DIFF_DISTCP stage it will force close all open files when
|
||||||
* there is no diff between the source path and the dst path. Otherwise
|
* there is no diff between the source path and the dst path. Otherwise
|
||||||
* the DIFF_DISTCP stage will wait until there is no open files. The
|
* the DIFF_DISTCP stage will wait until there is no open files. The
|
||||||
* default value is `false`.
|
* default value is `false`.
|
||||||
*/
|
*/
|
||||||
final static Option FORCE_CLOSE_OPEN = new Option("forceCloseOpen", false,
|
public final static Option FORCE_CLOSE_OPEN = new Option("forceCloseOpen",
|
||||||
"Force close all open files if the src and dst are synced.");
|
false, "Force close all open files if the src and dst are synced.");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max number of maps to use during copy. DistCp will split work as equally
|
* Max number of maps to use during copy. DistCp will split work as equally
|
||||||
* as possible among these maps.
|
* as possible among these maps.
|
||||||
*/
|
*/
|
||||||
final static Option MAP =
|
public final static Option MAP =
|
||||||
new Option("map", true, "Max number of concurrent maps to use for copy");
|
new Option("map", true, "Max number of concurrent maps to use for copy");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify bandwidth per map in MB, accepts bandwidth as a fraction.
|
* Specify bandwidth per map in MB, accepts bandwidth as a fraction.
|
||||||
*/
|
*/
|
||||||
final static Option BANDWIDTH =
|
public final static Option BANDWIDTH =
|
||||||
new Option("bandwidth", true, "Specify bandwidth per map in MB.");
|
new Option("bandwidth", true, "Specify bandwidth per map in MB.");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the delayed duration(millie seconds) to retry the Job.
|
* Specify the delayed duration(millie seconds) to retry the Job.
|
||||||
*/
|
*/
|
||||||
final static Option DELAY_DURATION = new Option("delay", true,
|
public final static Option DELAY_DURATION = new Option("delay", true,
|
||||||
"This specifies the delayed duration(millie seconds) when the job"
|
"This specifies the delayed duration(millie seconds) when the job"
|
||||||
+ " needs to retry. A job may retry many times and check the state"
|
+ " needs to retry. A job may retry many times and check the state"
|
||||||
+ " when it waits for the distcp job to finish.");
|
+ " when it waits for the distcp job to finish.");
|
||||||
|
@ -74,7 +63,7 @@ public final class FedBalanceOptions {
|
||||||
/**
|
/**
|
||||||
* Specify the threshold of diff entries.
|
* Specify the threshold of diff entries.
|
||||||
*/
|
*/
|
||||||
final static Option DIFF_THRESHOLD = new Option("diffThreshold", true,
|
public final static Option DIFF_THRESHOLD = new Option("diffThreshold", true,
|
||||||
"This specifies the threshold of the diff entries that used in"
|
"This specifies the threshold of the diff entries that used in"
|
||||||
+ " incremental copy stage. If the diff entries size is no greater"
|
+ " incremental copy stage. If the diff entries size is no greater"
|
||||||
+ " than this threshold and the open files check is satisfied"
|
+ " than this threshold and the open files check is satisfied"
|
||||||
|
@ -86,17 +75,16 @@ public final class FedBalanceOptions {
|
||||||
* Move the source path to trash after all the data are sync to target, or
|
* Move the source path to trash after all the data are sync to target, or
|
||||||
* delete the source directly, or skip both trash and deletion.
|
* delete the source directly, or skip both trash and deletion.
|
||||||
*/
|
*/
|
||||||
final static Option TRASH = new Option("moveToTrash", true,
|
public final static Option TRASH = new Option("moveToTrash", true,
|
||||||
"Move the source path to trash, or delete the source path directly,"
|
"Move the source path to trash, or delete the source path directly,"
|
||||||
+ " or skip both trash and deletion. This accepts 3 values: trash,"
|
+ " or skip both trash and deletion. This accepts 3 values: trash,"
|
||||||
+ " delete and skip. By default the server side trash interval is"
|
+ " delete and skip. By default the server side trash interval is"
|
||||||
+ " used. If the trash is disabled in the server side, the default"
|
+ " used. If the trash is disabled in the server side, the default"
|
||||||
+ " trash interval 60 minutes is used.");
|
+ " trash interval 60 minutes is used.");
|
||||||
|
|
||||||
final static Options CLI_OPTIONS = new Options();
|
public final static Options CLI_OPTIONS = new Options();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CLI_OPTIONS.addOption(ROUTER);
|
|
||||||
CLI_OPTIONS.addOption(FORCE_CLOSE_OPEN);
|
CLI_OPTIONS.addOption(FORCE_CLOSE_OPEN);
|
||||||
CLI_OPTIONS.addOption(MAP);
|
CLI_OPTIONS.addOption(MAP);
|
||||||
CLI_OPTIONS.addOption(BANDWIDTH);
|
CLI_OPTIONS.addOption(BANDWIDTH);
|
||||||
|
|
|
@ -45,10 +45,9 @@ Usage
|
||||||
|
|
||||||
The command below runs an hdfs federation balance job. The first parameter is
|
The command below runs an hdfs federation balance job. The first parameter is
|
||||||
the mount entry. The second one is the target path which must include the
|
the mount entry. The second one is the target path which must include the
|
||||||
target cluster. The option `-router` indicates this is in router-based
|
target cluster.
|
||||||
federation mode.
|
|
||||||
|
|
||||||
bash$ /bin/hadoop fedbalance -router submit /foo/src hdfs://namespace-1/foo/dst
|
bash$ /bin/hadoop rbfbalance -router submit /foo/src hdfs://namespace-1/foo/dst
|
||||||
|
|
||||||
It copies data from hdfs://namespace-0/foo/src to hdfs://namespace-1/foo/dst
|
It copies data from hdfs://namespace-0/foo/src to hdfs://namespace-1/foo/dst
|
||||||
incrementally and finally updates the mount entry to:
|
incrementally and finally updates the mount entry to:
|
||||||
|
@ -59,7 +58,7 @@ Usage
|
||||||
If the hadoop shell process exits unexpectedly, we can use the command below
|
If the hadoop shell process exits unexpectedly, we can use the command below
|
||||||
to continue the unfinished job:
|
to continue the unfinished job:
|
||||||
|
|
||||||
bash$ /bin/hadoop fedbalance continue
|
bash$ /bin/hadoop rbfbalance continue
|
||||||
|
|
||||||
This will scan the journal to find all the unfinished jobs, recover and
|
This will scan the journal to find all the unfinished jobs, recover and
|
||||||
continue to execute them.
|
continue to execute them.
|
||||||
|
@ -77,8 +76,8 @@ Usage
|
||||||
* the router-based federation mode (RBF mode).
|
* the router-based federation mode (RBF mode).
|
||||||
* the normal federation mode.
|
* the normal federation mode.
|
||||||
|
|
||||||
By default the command runs in the normal federation mode. You can specify the
|
The command `rbfbalance` runs in router-based federation mode. The command
|
||||||
rbf mode by using the option `-router`.
|
`fedbalance` runs in normal federation mode.
|
||||||
|
|
||||||
In the rbf mode the first parameter is taken as the mount point. It disables
|
In the rbf mode the first parameter is taken as the mount point. It disables
|
||||||
write by setting the mount point readonly.
|
write by setting the mount point readonly.
|
||||||
|
@ -91,11 +90,10 @@ Usage
|
||||||
|
|
||||||
### Command Options
|
### Command Options
|
||||||
|
|
||||||
Command `submit` has 5 options:
|
Command `submit` has 4 options:
|
||||||
|
|
||||||
| Option key | Description | Default |
|
| Option key | Description | Default |
|
||||||
| ------------------------------ | ------------------------------------ | ------- |
|
| ------------------------------ | ------------------------------------ | ------- |
|
||||||
| -router | Run in router-based federation mode. | Normal federation mode. |
|
|
||||||
| -forceCloseOpen | Force close all open files when there is no diff in the DIFF_DISTCP stage. | Wait until there is no open files. |
|
| -forceCloseOpen | Force close all open files when there is no diff in the DIFF_DISTCP stage. | Wait until there is no open files. |
|
||||||
| -map | Max number of concurrent maps to use for copy. | 10 |
|
| -map | Max number of concurrent maps to use for copy. | 10 |
|
||||||
| -bandwidth | Specify bandwidth per map in MB. | 10 |
|
| -bandwidth | Specify bandwidth per map in MB. | 10 |
|
||||||
|
@ -106,7 +104,7 @@ Command `submit` has 5 options:
|
||||||
### Configuration Options
|
### Configuration Options
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Set configuration options at fedbalance-site.xml.
|
Set configuration options at hdfs-fedbalance-site.xml.
|
||||||
|
|
||||||
| Configuration key | Description | Default |
|
| Configuration key | Description | Default |
|
||||||
| ------------------------------ | ------------------------------------ | ------- |
|
| ------------------------------ | ------------------------------------ | ------- |
|
||||||
|
@ -165,7 +163,7 @@ Architecture of HDFS Federation Balance
|
||||||
|
|
||||||
* MountTableProcedure: This procedure updates the mount entry in Router. The
|
* MountTableProcedure: This procedure updates the mount entry in Router. The
|
||||||
readonly is unset and the destination is updated of the mount point. This
|
readonly is unset and the destination is updated of the mount point. This
|
||||||
procedure is activated only when option `-router`.
|
procedure is activated only in router based federation mode.
|
||||||
|
|
||||||
* TrashProcedure: This procedure moves the source path to trash.
|
* TrashProcedure: This procedure moves the source path to trash.
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ public class TestDistCpProcedure {
|
||||||
FedBalanceContext context = buildContext(src, dst, MOUNT);
|
FedBalanceContext context = buildContext(src, dst, MOUNT);
|
||||||
DistCpProcedure dcProcedure =
|
DistCpProcedure dcProcedure =
|
||||||
new DistCpProcedure("distcp-procedure", null, 1000, context);
|
new DistCpProcedure("distcp-procedure", null, 1000, context);
|
||||||
dcProcedure.disableWrite();
|
dcProcedure.disableWrite(context);
|
||||||
dcProcedure.finish();
|
dcProcedure.finish();
|
||||||
|
|
||||||
// Verify path and permission.
|
// Verify path and permission.
|
||||||
|
@ -317,7 +317,8 @@ public class TestDistCpProcedure {
|
||||||
dcp[0] = serializeProcedure(dcp[0]);
|
dcp[0] = serializeProcedure(dcp[0]);
|
||||||
executeProcedure(dcp[0], Stage.DISABLE_WRITE, () -> dcp[0].diffDistCp());
|
executeProcedure(dcp[0], Stage.DISABLE_WRITE, () -> dcp[0].diffDistCp());
|
||||||
dcp[0] = serializeProcedure(dcp[0]);
|
dcp[0] = serializeProcedure(dcp[0]);
|
||||||
executeProcedure(dcp[0], Stage.FINAL_DISTCP, () -> dcp[0].disableWrite());
|
executeProcedure(dcp[0], Stage.FINAL_DISTCP,
|
||||||
|
() -> dcp[0].disableWrite(context));
|
||||||
dcp[0] = serializeProcedure(dcp[0]);
|
dcp[0] = serializeProcedure(dcp[0]);
|
||||||
OutputStream out = fs.append(new Path(src, "b/c"));
|
OutputStream out = fs.append(new Path(src, "b/c"));
|
||||||
executeProcedure(dcp[0], Stage.FINISH, () -> dcp[0].finalDistCp());
|
executeProcedure(dcp[0], Stage.FINISH, () -> dcp[0].finalDistCp());
|
||||||
|
@ -372,7 +373,7 @@ public class TestDistCpProcedure {
|
||||||
new DistCpProcedure("distcp-procedure", null, 1000, context);
|
new DistCpProcedure("distcp-procedure", null, 1000, context);
|
||||||
assertNotEquals(0, fs.getFileStatus(src).getPermission().toShort());
|
assertNotEquals(0, fs.getFileStatus(src).getPermission().toShort());
|
||||||
executeProcedure(dcProcedure, Stage.FINAL_DISTCP,
|
executeProcedure(dcProcedure, Stage.FINAL_DISTCP,
|
||||||
() -> dcProcedure.disableWrite());
|
() -> dcProcedure.disableWrite(context));
|
||||||
assertEquals(0, fs.getFileStatus(src).getPermission().toShort());
|
assertEquals(0, fs.getFileStatus(src).getPermission().toShort());
|
||||||
cleanup(fs, new Path(testRoot));
|
cleanup(fs, new Path(testRoot));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue