/** * 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 com.alibaba.jstorm.yarn.handler; import com.alibaba.jstorm.yarn.appmaster.JstormMaster; import com.alibaba.jstorm.yarn.constants.JOYConstants; import com.alibaba.jstorm.yarn.context.JstormMasterContext; import com.alibaba.jstorm.yarn.generated.JstormAM; import com.alibaba.jstorm.yarn.utils.JstormYarnUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.registry.client.api.BindFlags; import org.apache.hadoop.registry.client.binding.RegistryUtils; import org.apache.hadoop.registry.client.types.ServiceRecord; import org.apache.hadoop.yarn.api.records.Container; import org.apache.hadoop.yarn.client.api.AMRMClient; import org.apache.hadoop.yarn.client.api.async.AMRMClientAsync; import org.apache.thrift.TException; import java.io.IOException; import java.util.List; import java.util.concurrent.BlockingQueue; /** * Created by fengjian on 15/12/22. */ public class JstormAMHandler implements JstormAM.Iface { public JstormAMHandler(JstormMaster jm) { this.jstormMasterContext = jm.jstormMasterContext; this.jstormMaster = jm; amRMClient = jstormMasterContext.amRMClient; requestQueue = jstormMasterContext.requestBlockingQueue; } private static final Log LOG = LogFactory.getLog(JstormAMHandler.class); private AMRMClientAsync amRMClient; private BlockingQueue requestQueue; private JstormMasterContext jstormMasterContext; private JstormMaster jstormMaster; @Override public void addSupervisors(int number, int containerMemory, int containerVcores) throws TException { if (containerMemory > jstormMasterContext.maxMemory) { containerMemory = jstormMasterContext.maxMemory; } if (containerVcores > jstormMasterContext.maxVcores) { containerVcores = jstormMasterContext.maxVcores; } for (int i = 0; i < number; i++) { //set priority to 0 which identity this container is allocated for supervisor AMRMClient.ContainerRequest containerAsk = jstormMaster.setupContainerAskForRM(containerMemory, containerVcores, 0, "*"); try { requestQueue.put(containerAsk); } catch (InterruptedException e) { e.printStackTrace(); } amRMClient.addContainerRequest(containerAsk); jstormMasterContext.numRequestedContainers.getAndIncrement(); } } @Override public void addSpecSupervisor(int number, int container_memory, int container_vcorecount, List<String> racks, List<String> hosts) throws TException { LOG.info("number:" + number + "; memory:" + container_memory + "; vcore:" + container_vcorecount + "; racks:" + JstormYarnUtils.join(racks, ",", false)); LOG.info("hosts:" + JstormYarnUtils.join(hosts, ",", false)); if (container_memory > jstormMasterContext.maxMemory) { container_vcorecount = jstormMasterContext.maxMemory; } if (container_vcorecount > jstormMasterContext.maxVcores) { container_vcorecount = jstormMasterContext.maxVcores; } for (int i = 0; i < number; i++) { AMRMClient.ContainerRequest containerAsk = jstormMaster.setupContainerAskForRM(container_memory, container_vcorecount, 0, racks.toArray(new String[0]), hosts.toArray(new String[0])); try { requestQueue.put(containerAsk); } catch (InterruptedException e) { e.printStackTrace(); } amRMClient.addContainerRequest(containerAsk); jstormMasterContext.numRequestedContainers.getAndIncrement(); } } @Override public String info() throws TException { StringBuffer sbRet = new StringBuffer(); sbRet.append("JstormOnYarn\n"); sbRet.append("Instance Name:" + jstormMasterContext.instanceName + "\n"); sbRet.append("Jstorm's location on hdfs:" + jstormMasterContext.deployPath + "\n"); if (jstormMasterContext.user != null) { sbRet.append("Jstorm's data path:" + jstormMasterContext.nimbusDataDirPrefix + jstormMasterContext.instanceName + "\n"); sbRet.append("Cluster userName:" + jstormMasterContext.user + "\n"); } sbRet.append("Nimbus Count:" + jstormMasterContext.nimbusContainers.size() + "\n"); sbRet.append("Supervisor Count:" + jstormMasterContext.supervisorContainers.size() + "\n"); sbRet.append("detail :\n"); sbRet.append("Type \tContainerId \tHost \tContainerMemory\tContainerVCores\n"); for (Container container : jstormMasterContext.nimbusContainers) { sbRet.append("Nimbus \t" + container.getId().toString() + "\t" + container.getNodeId().getHost() + "\t" + container.getResource().getMemory() + "\t " + container.getResource().getVirtualCores() + "\n"); } for (Container container : jstormMasterContext.supervisorContainers) { sbRet.append("Supervisor\t" + container.getId().toString() + "\t" + container.getNodeId().getHost() + "\t" + container.getResource().getMemory() + "\t " + container.getResource().getVirtualCores() + "\n"); } LOG.info("info is: " + sbRet.toString()); return sbRet.toString(); } @Override public void stopAppMaster() throws TException { stopNimbus(); stopSupervisors(); jstormMaster.killApplicationMaster(); } @Override public void startSpecNimbus(int number, int containerMemory, int containerVirtualCores, List<String> racks, List<String> hosts) throws TException { //set priority to 1 which identity this container is allocated for nimbus String dstHost = "*"; if (!jstormMasterContext.previousNimbusHost.equals("") && jstormMasterContext.nimbusContainers.size() == 0) dstHost = jstormMasterContext.previousNimbusHost; LOG.info("dstHost:" + dstHost); AMRMClient.ContainerRequest containerAsk = jstormMaster.setupContainerAskForRM(containerMemory, containerVirtualCores, 1, racks.toArray(new String[0]), hosts.toArray(new String[0])); try { requestQueue.put(containerAsk); } catch (InterruptedException e) { e.printStackTrace(); } amRMClient.addContainerRequest(containerAsk); jstormMasterContext.numRequestedContainers.getAndIncrement(); } @Override public void startNimbus(int number, int containerMemory, int containerVirtualCores) throws TException { //set priority to 1 which identity this container is allocated for nimbus String dstHost = "*"; if (!jstormMasterContext.previousNimbusHost.equals("") && jstormMasterContext.nimbusContainers.size() == 0) dstHost = jstormMasterContext.previousNimbusHost; LOG.info("dstHost:" + dstHost); AMRMClient.ContainerRequest containerAsk = jstormMaster.setupContainerAskForRM(containerMemory, containerVirtualCores, 1, dstHost); try { requestQueue.put(containerAsk); } catch (InterruptedException e) { e.printStackTrace(); } amRMClient.addContainerRequest(containerAsk); jstormMasterContext.numRequestedContainers.getAndIncrement(); } @Override public void stopNimbus() throws TException { if (jstormMasterContext.nimbusContainers.isEmpty()) return; int nimbusCount = jstormMasterContext.nimbusContainers.size(); for (int i = 0; i < nimbusCount; i++) { Container container = jstormMasterContext.nimbusContainers.poll(); if (container != null) { amRMClient.releaseAssignedContainer(container.getId()); LOG.info("release nimbus container, id: " + container.getId().toString()); } } } @Override public void removeNimbus(int number) throws TException { if (jstormMasterContext.nimbusContainers.isEmpty()) return; for (int i = 0; i < number; i++) { Container container = jstormMasterContext.nimbusContainers.poll(); if (container != null) { amRMClient.releaseAssignedContainer(container.getId()); LOG.info("release nimbus container, id: " + container.getId().toString()); } } } @Override public void removeSpecNimbus(String container_id) throws TException { if (jstormMasterContext.nimbusContainers.isEmpty()) return; for (Container container : jstormMasterContext.nimbusContainers) { if (container.getId().toString().trim().equals(container_id.trim())) { jstormMasterContext.nimbusContainers.remove(container); amRMClient.releaseAssignedContainer(container.getId()); } } } @Override public void startSupervisors() throws TException { } @Override public void stopSupervisors() throws TException { if (jstormMaster.jstormMasterContext.supervisorContainers.isEmpty()) return; int supervisorCount = jstormMaster.jstormMasterContext.supervisorContainers.size(); for (int i = 0; i < supervisorCount; i++) { Container container = jstormMaster.jstormMasterContext.supervisorContainers.poll(); if (container != null) { amRMClient.releaseAssignedContainer(container.getId()); LOG.info("release all supervisor container, id: " + container.getId().toString()); } } } @Override public void removeSupervisors(int number) throws TException { if (jstormMaster.jstormMasterContext.supervisorContainers.isEmpty()) return; for (int i = 0; i < number; i++) { Container container = jstormMaster.jstormMasterContext.supervisorContainers.poll(); if (container != null) { amRMClient.releaseAssignedContainer(container.getId()); LOG.info("release supervisor's " + String.valueOf(number) + " container, id: " + container.getId().toString()); } } } @Override public void removeSpecSupervisors(String container_id) throws TException { LOG.info("remove spec supervisor: " + container_id); for (Container container : jstormMaster.jstormMasterContext.supervisorContainers) { if (container.getId().toString().trim().equals(container_id.trim())) { LOG.info("found one remove"); jstormMaster.jstormMasterContext.supervisorContainers.remove(container); amRMClient.releaseAssignedContainer(container.getId()); return; } } LOG.info("remove spec nimbus : " + container_id); for (Container container : jstormMaster.jstormMasterContext.nimbusContainers) { if (container.getId().toString().trim().equals(container_id.trim())) { LOG.info("found one remove"); jstormMaster.jstormMasterContext.nimbusContainers.remove(container); amRMClient.releaseAssignedContainer(container.getId()); } } } @Override public void upgradeCluster() throws TException { for (Container supervisorContainer : jstormMaster.jstormMasterContext.supervisorContainers) { //upgrade supervisor String containerPath = RegistryUtils.componentPath( JOYConstants.APP_TYPE, jstormMasterContext.instanceName, supervisorContainer.getId().getApplicationAttemptId().getApplicationId().toString(), supervisorContainer.getId().toString()); try { if (jstormMaster.registryOperations.exists(containerPath)) { ServiceRecord sr = jstormMaster.registryOperations.resolve(containerPath); sr.set("needUpgrade", "true"); jstormMaster.registryOperations.bind(containerPath, sr, BindFlags.OVERWRITE); } } catch (IOException e) { e.printStackTrace(); } } for (Container nimbusContainer : jstormMaster.jstormMasterContext.nimbusContainers) { //upgrade nimbus String containerPath = RegistryUtils.componentPath( JOYConstants.APP_TYPE, jstormMasterContext.instanceName, nimbusContainer.getId().getApplicationAttemptId().getApplicationId().toString(), nimbusContainer.getId().toString()); try { if (jstormMaster.registryOperations.exists(containerPath)) { ServiceRecord sr = jstormMaster.registryOperations.resolve(containerPath); sr.set("needUpgrade", "true"); jstormMaster.registryOperations.bind(containerPath, sr, BindFlags.OVERWRITE); } } catch (IOException e) { e.printStackTrace(); } } } @Override public void shutdown() throws TException { } @Override public String getConfig() throws TException { StringBuffer sbRet = new StringBuffer(); sbRet.append("Jstorm's location on hdfs:" + jstormMasterContext.deployPath + "\n"); if (jstormMasterContext.nimbusDataDirPrefix != null) sbRet.append("Jstorm's data path:" + jstormMasterContext.nimbusDataDirPrefix + jstormMasterContext.instanceName + "\n"); if (jstormMasterContext.user != null) { sbRet.append("Cluster username:" + jstormMasterContext.user + "\n"); sbRet.append("Cluster password:" + "***" + jstormMasterContext.password.substring(3, jstormMasterContext.password.length() - 2) + "**" + "\n"); sbRet.append("Cluster oldpassword:" + "***" + jstormMasterContext.oldPassword.substring(3, jstormMasterContext.oldPassword.length() - 2) + "**" + "\n"); } return sbRet.toString(); } @Override public void setConfig(String key, String value) throws TException { if (key.equals("password")) { jstormMasterContext.password = value; } else if (key.equals("oldpassword")) { jstormMasterContext.oldPassword = value; } else if (key.equals("username")) { jstormMasterContext.user = value; } } }