From b350b8b6f2ce29b2d026911e99d2264d26c81a3f Mon Sep 17 00:00:00 2001 From: "gavin.wang" Date: Tue, 23 Jul 2024 15:27:27 +0800 Subject: [PATCH] Make yarn rmadmin tool support failover function --- .../hadoop/yarn/client/cli/RMAdminCLI.java | 59 ++++++++++++++++--- .../yarn/client/cli/TestRMAdminCLI.java | 23 ++++---- 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/RMAdminCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/RMAdminCLI.java index dd596aad56635..39e7abfb6bd91 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/RMAdminCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/RMAdminCLI.java @@ -43,6 +43,9 @@ import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.ha.HAAdmin; import org.apache.hadoop.ha.HAServiceTarget; +import org.apache.hadoop.ha.ServiceFailedException; +import org.apache.hadoop.ha.HAServiceProtocol; +import org.apache.hadoop.ha.HAServiceProtocolHelper; import org.apache.hadoop.ipc.RemoteException; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.ToolRunner; @@ -172,6 +175,14 @@ public class RMAdminCLI extends HAAdmin { "Update resource on specific node.")) .build(); + private final static Map YARN_HA_USAGE = + ImmutableMap. builder() + .put("-failover", new UsageInfo( + " ", + "Failover from the first service to the second.\n")) + .putAll(USAGE) + .build(); + public RMAdminCLI() { super(); } @@ -189,7 +200,7 @@ protected void setOut(PrintStream out) { } private static void appendHAUsage(final StringBuilder usageBuilder) { - for (Map.Entry cmdEntry : USAGE.entrySet()) { + for (Map.Entry cmdEntry : YARN_HA_USAGE.entrySet()) { if (cmdEntry.getKey().equals("-help")) { continue; } @@ -206,7 +217,7 @@ private static void appendHAUsage(final StringBuilder usageBuilder) { private static void buildHelpMsg(String cmd, StringBuilder builder) { UsageInfo usageInfo = ADMIN_USAGE.get(cmd); if (usageInfo == null) { - usageInfo = USAGE.get(cmd); + usageInfo = YARN_HA_USAGE.get(cmd); if (usageInfo == null) { return; } @@ -225,7 +236,7 @@ private static void buildIndividualUsageMsg(String cmd, boolean isHACommand = false; UsageInfo usageInfo = ADMIN_USAGE.get(cmd); if (usageInfo == null) { - usageInfo = USAGE.get(cmd); + usageInfo = YARN_HA_USAGE.get(cmd); if (usageInfo == null) { return; } @@ -246,12 +257,12 @@ private static void buildIndividualUsageMsg(String cmd, private static void buildUsageMsg(StringBuilder builder, boolean isHAEnabled) { builder.append("Usage: yarn rmadmin\n"); - for (Map.Entry cmdEntry : ADMIN_USAGE.entrySet()) { + for (Map.Entry cmdEntry : ADMIN_USAGE.entrySet()) { UsageInfo usageInfo = cmdEntry.getValue(); builder.append(" " + cmdEntry.getKey() + " " + usageInfo.args + "\n"); } if (isHAEnabled) { - for (Map.Entry cmdEntry : USAGE.entrySet()) { + for (Map.Entry cmdEntry : YARN_HA_USAGE.entrySet()) { String cmdKey = cmdEntry.getKey(); if (!cmdKey.equals("-help")) { UsageInfo usageInfo = cmdEntry.getValue(); @@ -304,7 +315,7 @@ private static void printHelp(String cmd, boolean isHAEnabled) { helpBuilder.append("\n"); } if (isHAEnabled) { - for (String cmdKey : USAGE.keySet()) { + for (String cmdKey : YARN_HA_USAGE.keySet()) { if (!cmdKey.equals("-help")) { buildHelpMsg(cmdKey, helpBuilder); helpBuilder.append("\n"); @@ -324,7 +335,7 @@ private static void printHelp(String cmd, boolean isHAEnabled) { */ private static void printUsage(String cmd, boolean isHAEnabled) { StringBuilder usageBuilder = new StringBuilder(); - if (ADMIN_USAGE.containsKey(cmd) || USAGE.containsKey(cmd)) { + if (ADMIN_USAGE.containsKey(cmd) || YARN_HA_USAGE.containsKey(cmd)) { buildIndividualUsageMsg(cmd, usageBuilder); } else { buildUsageMsg(usageBuilder, isHAEnabled); @@ -757,6 +768,28 @@ private int replaceLabelsOnNodes(Map> map, return 0; } + private int failover(CommandLine cmd) + throws IOException, ServiceFailedException { + int numOpts = cmd.getOptions() == null ? 0 : cmd.getOptions().length; + final String[] args = cmd.getArgs(); + if (numOpts > 1 || args.length != 2) { + errOut.println("failover: incorrect arguments"); + printUsage(errOut, "-failover", YARN_HA_USAGE); + return -1; + } + HAServiceTarget fromNode = resolveTarget(args[0]); + HAServiceTarget toNode = resolveTarget(args[1]); + setRequestSource(HAServiceProtocol.RequestSource.REQUEST_BY_USER_FORCED); + HAServiceProtocol proto = fromNode.getProxy( + getConf(), 0); + HAServiceProtocolHelper.transitionToStandby(proto, createReqInfo()); + HAServiceProtocol proto1 = toNode.getProxy( + getConf(), 0); + HAServiceProtocolHelper.transitionToActive(proto1, createReqInfo()); + out.println("Failover from "+args[0]+" to "+args[1]+" successful"); + return 0; + } + @Override public int run(String[] args) throws Exception { YarnConfiguration yarnConf = @@ -792,6 +825,18 @@ public int run(String[] args) throws Exception { System.out.println("Cannot run " + cmd + " when ResourceManager HA is not enabled"); return -1; + }else if("-failover".equals(cmd)) { + if (isHAEnabled) { + Options opts = new Options(); + CommandLine cmdLine = parseOpts(cmd, opts, args, YARN_HA_USAGE); + if (cmdLine == null) { + return -1; + } + return failover(cmdLine); + } + System.out.println("Cannot run " + cmd + + " when ResourceManager HA is not enabled"); + return -1; } // diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestRMAdminCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestRMAdminCLI.java index 40cde4fe11b36..6d32f36ff1b5f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestRMAdminCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestRMAdminCLI.java @@ -624,6 +624,16 @@ public void testTransitionToStandby() throws Exception { any(HAServiceProtocol.StateChangeRequestInfo.class)); } + @Test + public void testFailover() throws Exception { + String[] args = {"-failover", "rm1", "rm2"}; + // RM HA is disabled. + // failover should not be executed + assertEquals(-1, rmAdminCLI.run(args)); + // failover should be executed + assertEquals(0, rmAdminCLIWithHAEnabled.run(args)); + } + @Test public void testGetServiceState() throws Exception { String[] args = {"-getServiceState", "rm1"}; @@ -768,6 +778,8 @@ public void testHelp() throws Exception { "Usage: yarn rmadmin [-refreshServiceAcl]", dataErr, 0); testError(new String[] { "-help", "-getGroups" }, "Usage: yarn rmadmin [-getGroups [username]]", dataErr, 0); + testError(new String[] { "-help", "-failover" }, + "Usage: yarn rmadmin [-failover ]", dataErr, 0); testError(new String[] { "-help", "-transitionToActive" }, "Usage: yarn rmadmin [-transitionToActive [--forceactive]" + " ]", dataErr, 0); @@ -802,6 +814,7 @@ public void testHelp() throws Exception { + "([OvercommitTimeout]) " + "or -updateNodeResource [NodeID] [ResourceTypes] " + "([OvercommitTimeout])] " + + "[-failover ] " + "[-transitionToActive [--forceactive] ] " + "[-transitionToStandby ] " + "[-getServiceState ] [-getAllServiceState] " @@ -1083,21 +1096,11 @@ public void testNoUnsupportedHACommandsInHelp() throws Exception { errOut = dataErr.toString(); assertTrue(errOut.contains("transitionToObserver: Unknown command")); dataErr.reset(); - args1[0] = "-failover"; - assertEquals(-1, rmAdminCLIWithHAEnabled.run(args1)); - errOut = dataErr.toString(); - assertTrue(errOut.contains("failover: Unknown command")); - dataErr.reset(); String[] args2 = {"-help", "-transitionToObserver"}; assertEquals(0, rmAdminCLIWithHAEnabled.run(args2)); errOut = dataErr.toString(); assertFalse(errOut.contains("-transitionToObserver")); dataErr.reset(); - args2[1] = "-failover"; - assertEquals(0, rmAdminCLIWithHAEnabled.run(args2)); - errOut = dataErr.toString(); - assertFalse(errOut.contains("-failover")); - dataErr.reset(); } @Test