diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/pom.xml hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/pom.xml index 91dc26c..940c18e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/pom.xml +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/pom.xml @@ -228,6 +228,13 @@ test-compile + + + + org.apache.hadoop.test.YarnTestDriver + + + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/test/YarnTestDriver.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/test/YarnTestDriver.java new file mode 100644 index 0000000..3c2736b --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/test/YarnTestDriver.java @@ -0,0 +1,61 @@ +/** + * 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.test; + +import org.apache.hadoop.util.ProgramDriver; +import org.apache.hadoop.yarn.server.resourcemanager.recovery.TestZKRMStateStorePerf; + +/** + * Driver for Yarn tests. + * + */ +public class YarnTestDriver { + + private ProgramDriver pgd; + + public YarnTestDriver() { + this(new ProgramDriver()); + } + + public YarnTestDriver(ProgramDriver pgd) { + this.pgd = pgd; + try { + pgd.addClass(TestZKRMStateStorePerf.class.getSimpleName(), + TestZKRMStateStorePerf.class, + "ZKRMStateStore i/o benchmark."); + } catch(Throwable e) { + e.printStackTrace(); + } + } + + public void run(String argv[]) { + int exitCode = -1; + try { + exitCode = pgd.run(argv); + } catch(Throwable e) { + e.printStackTrace(); + } + System.exit(exitCode); + } + + public static void main(String argv[]){ + new YarnTestDriver().run(argv); + } +} + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java index 507e164..13a581c 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/RMStateStoreTestBase.java @@ -130,7 +130,8 @@ void waitNotify(TestDispatcher dispatcher) { dispatcher.notified = false; } - RMApp storeApp(RMStateStore store, ApplicationId appId, long submitTime, + protected RMApp storeApp(RMStateStore store, ApplicationId appId, + long submitTime, long startTime) throws Exception { ApplicationSubmissionContext context = new ApplicationSubmissionContextPBImpl(); @@ -146,7 +147,8 @@ RMApp storeApp(RMStateStore store, ApplicationId appId, long submitTime, return mockApp; } - ContainerId storeAttempt(RMStateStore store, ApplicationAttemptId attemptId, + protected ContainerId storeAttempt(RMStateStore store, + ApplicationAttemptId attemptId, String containerIdStr, Token appToken, SecretKey clientTokenMasterKey, TestDispatcher dispatcher) throws Exception { @@ -450,7 +452,7 @@ public void testRMDTSecretManagerStateStore( } - private Token generateAMRMToken( + protected Token generateAMRMToken( ApplicationAttemptId attemptId, AMRMTokenSecretManager appTokenMgr) { AMRMTokenIdentifier appTokenId = diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStorePerf.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStorePerf.java new file mode 100644 index 0000000..67b4b5b --- /dev/null +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStorePerf.java @@ -0,0 +1,221 @@ +/** + * 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.yarn.server.resourcemanager.recovery; + +import com.google.common.base.Optional; +import java.util.ArrayList; +import javax.crypto.SecretKey; +import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.util.Tool; +import org.apache.hadoop.util.ToolRunner; +import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.api.records.ContainerId; +import org.apache.hadoop.yarn.security.AMRMTokenIdentifier; +import org.apache.hadoop.yarn.server.resourcemanager.security + .AMRMTokenSecretManager; +import org.apache.hadoop.yarn.server.resourcemanager.security + .ClientToAMTokenSecretManagerInRM; +import org.junit.After; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.junit.Before; +import org.junit.Test; + +public class TestZKRMStateStorePerf extends RMStateStoreTestBase implements Tool { + public static final Log LOG = LogFactory.getLog(TestZKRMStateStore.class); + + final String version = "0.1"; + + // Configurable variables for performance test + private int ZK_PERF_NUM_APP_DEFAULT = 100; + private int ZK_PERF_NUM_APPATTEMPT_PER_APP = 100; + + private static final int ZK_TIMEOUT_MS = 100000; + private final long clusterTimeStamp = 1352994193343L; + + private static final String USAGE = + "Usage: " + TestZKRMStateStorePerf.class.getSimpleName() + + " -appSize numberOfApplications" + + " -appAttemptSize numberOfApplicationAttempts" + + " [-hostPort Host:Port]" + + " [-workingZnode rootZnodeForTesting]"; + + private YarnConfiguration conf = null; + private String workingZnode = "/Test"; + private ZKRMStateStore store; + private AMRMTokenSecretManager appTokenMgr; + private ClientToAMTokenSecretManagerInRM clientToAMTokenMgr; + + @Before + public void setUpZKServer() throws Exception { + super.setUp(); + } + + @After + public void tearDown() throws Exception { + if (store != null) { + store.stop(); + } + if (appTokenMgr != null) { + appTokenMgr.stop(); + } + super.tearDown(); + } + + private void initStore(String hostPort) { + Optional optHostPort = Optional.fromNullable(hostPort); + + if (conf == null) { + conf = new YarnConfiguration(); + conf.set(YarnConfiguration.RM_ZK_ADDRESS, optHostPort.or(this.hostPort)); + conf.set(YarnConfiguration.ZK_RM_STATE_STORE_PARENT_PATH, workingZnode); + } + + store = new ZKRMStateStore(); + store.init(conf); + store.start(); + appTokenMgr = new AMRMTokenSecretManager(conf); + clientToAMTokenMgr = new ClientToAMTokenSecretManagerInRM(); + } + + @Override + public int run(String[] args) throws Exception { + LOG.info("Starting ZKRMStateStorePerf ver." + version); + + int numApp = ZK_PERF_NUM_APP_DEFAULT; + int numAppAttemptPerApp = ZK_PERF_NUM_APPATTEMPT_PER_APP; + String hostPort = null; + boolean launchLocalZK= true; + + if (args.length == 0) { + System.err.println("Missing arguments."); + return -1; + } + + for (int i = 0; i < args.length; i++) { // parse command line + if (args[i].equalsIgnoreCase("-appsize")) { + numApp = Integer.parseInt(args[++i]); + } else if (args[i].equalsIgnoreCase("-attemptsize")) { + numAppAttemptPerApp = Integer.parseInt(args[++i]); + } else if (args[i].equalsIgnoreCase("-hostPort")) { + hostPort = args[++i]; + launchLocalZK = false; + } else if (args[i].equalsIgnoreCase("-workingZnode")) { + workingZnode = args[++i]; + } else { + System.err.println("Illegal argument: " + args[i]); + return -1; + } + } + + //validate(numApp, numAppAttemptPerApp); + + if (launchLocalZK) { + setUp(); + } + + initStore(hostPort); + + long submitTime = System.currentTimeMillis(); + long startTime = System.currentTimeMillis() + 1234; + + ArrayList applicationIds = new ArrayList(); + ArrayList attemptIds = + new ArrayList(); + ArrayList containerIds = new ArrayList(); + TestDispatcher dispatcher = new TestDispatcher(); + store.setRMDispatcher(dispatcher); + + for (int i = 0; i < numApp; i++) { + ApplicationId appId = ApplicationId.newInstance(clusterTimeStamp, i); + applicationIds.add(appId); + for (int j = 0; j < numAppAttemptPerApp; j++) { + ApplicationAttemptId attemptId = + ApplicationAttemptId.newInstance(appId, j); + attemptIds.add(attemptId); + } + } + + for (ApplicationId appId : applicationIds) { + storeApp(store, appId, submitTime, startTime); + } + + for (ApplicationAttemptId attemptId : attemptIds) { + Token tokenId = + generateAMRMToken(attemptId, appTokenMgr); + SecretKey clientTokenKey = + clientToAMTokenMgr.createMasterKey(attemptId); + storeAttempt(store, attemptId, + ContainerId.newInstance(attemptId, 0).toString(), + tokenId, clientTokenKey, dispatcher); + } + + long storeStart = System.currentTimeMillis(); + store.loadState(); + long storeEnd = System.currentTimeMillis(); + + long loadTime = storeEnd - storeStart; + + String resultMsg = "ZKRMStateStore takes " + loadTime + " msec to loadState."; + LOG.info(resultMsg); + System.out.println(resultMsg); + + return 0; + } + + @Override + public void setConf(Configuration conf) { + this.conf = new YarnConfiguration(conf); + } + + @Override + public Configuration getConf() { + return conf; + } + + @Test + public void perfZKRMStateStore() throws Exception { + String[] args = { + "-appSize", String.valueOf(ZK_PERF_NUM_APP_DEFAULT), + "-appAttemptSize", String.valueOf(ZK_PERF_NUM_APPATTEMPT_PER_APP) + }; + run(args); + } + + static public void main(String[] args) throws Exception { + TestZKRMStateStorePerf perf = new TestZKRMStateStorePerf(); + + int res = -1; + try { + res = ToolRunner.run(perf, args); + } catch(Exception e) { + System.err.print(StringUtils.stringifyException(e)); + res = -2; + } + if(res == -1) { + System.err.print(USAGE); + } + System.exit(res); + } +}