blob: bff01dad4ee372170cc42f285230e0f5dcc619fd [file] [log] [blame]
<?php
/*
* 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.
*/
class SelectNodes {
private $logger;
/**
* Needs a default constructor else warnings will appear.
*/
function __construct() {
$this->logger = new HMCLogger("SelectNodes");
}
/** Helper function for creating an array for hostName and totalMem
*/
function createHostMap($hostInfo) {
$result = array("hostNames" => array($hostInfo["hostName"]));
return $result;
}
/** Return only the enabled services.
*/
function filterEnabledServices($services) {
$enabledServices = array();
foreach($services as $serviceName=>$serviceInfo) {
if ($serviceInfo["isEnabled"] == 1) {
$enabledServices[$serviceName] = $serviceInfo;
}
}
return $enabledServices;
}
/**
* Helper function to add HDFS NameNode
*/
function addNameNode($serviceInfo, $result, $hostInfo) {
if (array_key_exists("HDFS", $serviceInfo)) {
$result["mastersToHosts"]["NAMENODE"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add SNameNode
*/
function addSNameNode($serviceInfo, $result, $hostInfo) {
if (array_key_exists("HDFS", $serviceInfo)) {
$result["mastersToHosts"]["SNAMENODE"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add JobTracker.
*/
function addJobTracker($serviceInfo, $result, $hostInfo) {
if (array_key_exists("MAPREDUCE", $serviceInfo)) {
$result["mastersToHosts"]["JOBTRACKER"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add HBase Master.
*/
function addHBaseMaster($serviceInfo, $result, $hostInfo) {
if (array_key_exists("HBASE", $serviceInfo)) {
$result["mastersToHosts"]["HBASE_MASTER"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add Oozie server.
*/
function addOozieServer($serviceInfo, $result, $hostInfo) {
if (array_key_exists("OOZIE", $serviceInfo)) {
$result["mastersToHosts"]["OOZIE_SERVER"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add Hive Server.
*/
function addHiveServer($serviceInfo, $result, $hostInfo) {
if (array_key_exists("HIVE", $serviceInfo)) {
$result["mastersToHosts"]["HIVE_SERVER"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add Templeton.
*/
function addTempletonServer($serviceInfo, $result, $hostInfo) {
if (array_key_exists("TEMPLETON", $serviceInfo)) {
$result["mastersToHosts"]["TEMPLETON_SERVER"] = $this->createHostMap($hostInfo);
}
return $result;
}
/**
* Helper function to add ZooKeeper master server.
*/
function addZooKeeperServer($serviceInfo, $result, $hostInfo) {
if (array_key_exists("ZOOKEEPER", $serviceInfo)) {
if (array_key_exists("ZOOKEEPER_SERVER", $result["mastersToHosts"])) {
array_push($result["mastersToHosts"]["ZOOKEEPER_SERVER"]["hostNames"],
$hostInfo["hostName"]);
} else {
$result["mastersToHosts"]["ZOOKEEPER_SERVER"] = $this->createHostMap($hostInfo);
}
}
return $result;
}
/**
* Helper function to add Ganglia master server.
*/
function addGangliaServer($result, $hostInfo) {
$result["mastersToHosts"]["GANGLIA_MONITOR_SERVER"] = $this->createHostMap($hostInfo);
return $result;
}
/**
* Helper function to add Nagios server.
*/
function addNagiosServer($result, $hostInfo) {
$result["mastersToHosts"]["NAGIOS_SERVER"] = $this->createHostMap($hostInfo);
return $result;
}
/**
* Adds all the slaves to the hostlist given whats enabled
*/
function addSlaves($db, $hostlist, $clusterName, $services, $gangliaMaster) {
$db->addHostsToComponent($clusterName, "TASKTRACKER", $hostlist, "ASSIGNED", "");
$db->addHostsToComponent($clusterName, "DATANODE", $hostlist, "ASSIGNED", "");
if (array_key_exists("HBASE", $services)) {
$db->addHostsToComponent($clusterName, "HBASE_REGIONSERVER", $hostlist, "ASSIGNED", "");
}
if (array_key_exists("GANGLIA", $services)) {
if (sizeof($hostlist) > 0) {
$db->addHostsToComponent($clusterName, "GANGLIA_MONITOR", $hostlist, "ASSIGNED", "");
}
}
}
/**
* Return a list of hosts excluding the ones in
* $excludeHosts
*/
function getExcludeHosts($allHosts, $excludeHosts) {
$result = array();
$found = FALSE;
foreach ($allHosts as $host) {
foreach($excludeHosts as $exclude) {
if ($host == $exclude) {
$found = TRUE;
break;
}
$found = FALSE;
}
if (!$found) {
array_push($result, $host);
}
}
return $result;
}
/**
* Return a list of slaves given what machines
* masters are running on given the set of all host
* and services enabled.
*/
function getSlaveList($allHosts, $masterToHost, $services) {
$result = array();
$numNodes = sizeof($allHosts);
if ($numNodes == 1) {
array_push($result, $allHosts[0]);
return $result;
}
if ($numNodes <= 5) {
/* all slaves except for the namenode */
$excludeList = $this->getExcludeHosts($allHosts, $masterToHost["NAMENODE"]);
return $excludeList;
}
if ($numNodes > 5) {
/* all slaves except for the namenode/JT/Hbase master */
$excludeHosts = array();
array_push($excludeHosts, $masterToHost["NAMENODE"][0]);
array_push($excludeHosts, $masterToHost["JOBTRACKER"][0]);
if (array_key_exists("HBASE", $services)) {
array_push($excludeHosts, $masterToHost["HBASE_MASTER"][0]);
}
$excludeList = $this->getExcludeHosts($allHosts, $excludeHosts);
return $excludeList;
}
}
/**
* convert hostInfo to a flat list
*/
function convertHostInfoToList($hostsInfo) {
$result = array();
foreach($hostsInfo as $host) {
array_push($result, $host["hostName"]);
}
return $result;
}
/**
* Function to update the DB with roles on what user has selected.
* This also selects the DataNodes/TaskTrackers/RegionServers based
* on what services were picked.
* @return Error or not
* array("result" => $result, "error" => $error)
* @param clusterName name of the cluster
* @param db the database being used
* @param masterToHost the master to Host mapping that the user selected
* array("componentName" => hostName")
*/
public function updateDBWithRoles($clusterName, $db, $masterToHost) {
$return = array();
$return["result"] = 0;
$return["error"] = "";
$this->logger->log_info("Updating with Info from User: \n".$clusterName."\n "
.print_r($masterToHost, true));
$allHostsDBInfo = $db->getAllHostsInfo($clusterName,
array("=" => array ( "discoveryStatus" => "SUCCESS")), array());
if ($allHostsDBInfo["result"] != 0) {
$this->logger->log_error("Issue getting all hosts info ".$allHostsDBInfo["error"]);
$return["result"] = $allHostsDBInfo["result"];
$return["error"] = $allHostsDBInfo["error"];
return $return;
}
$allHosts_t = $allHostsDBInfo["hosts"];
/* get all enabled services */
$servicesDBInfo = $db->getAllServicesInfo($clusterName);
if ($servicesDBInfo["result"] != 0) {
$this->logger->log_error("Issue getting all services enabled ".$allHostsDBInfo["error"]);
$return["result"] = $servicesDBInfo["result"];
$return["error"] = $servicesDBInfo["error"];
return $return;
}
$services_tmp = $servicesDBInfo["services"];
$services = $this->filterEnabledServices($services_tmp);
$clusterInfo = $db->getClusterState($clusterName);
if ($clusterInfo["result"] != 0) {
$this->logger->log_error("Error getting cluster state ". $clusterInfo["error"]);
$return["result"] = $clusterInfo["result"];
$return["error"] = $clusterInfo["error"];
return $return;
}
$clusterState = json_decode($clusterInfo[state],true);
if($clusterState[state] == "CONFIGURATION_IN_PROGRESS") {
$hostRolesResult = $db->cleanAllHostRoles($clusterName);
if ($hostRolesResult["result"] != 0) {
$this->logger->log_error("Issue cleaning all host roles ".$hostRolesResult["error"]);
$return["result"] = $hostRolesResult["result"];
$return["error"] = $hostRolesResult["error"];
return $return;
}
}
$allHosts = $this->convertHostInfoToList($allHosts_t);
foreach($masterToHost as $componentName=>$hostNames) {
$this->logger->log_info("For cluster $clusterName setting $componentName to host \n". print_r($hostNames, true));
$db->addHostsToComponent($clusterName, $componentName, $hostNames, "ASSIGNED", "");
if ($componentName == "GANGLIA_MONITOR_SERVER") {
$gangliaMaster = $hostNames[0];
}
if ($componentName == "ZOOKEEPER_SERVER") {
$sizeHosts = sizeof($hostNames);
if ($sizeHosts == 1) {
$hostConfig = array ( "ZOOKEEPER_SERVER" => array( $hostNames[0] => array ( "myid" => 1 )));
$db->updateHostRoleConfigs($clusterName, $hostConfig);
} else {
$hostConfig = array( "ZOOKEEPER_SERVER" => array() );
for ($i=0; $i < 3; $i++) {
$hostConfig["ZOOKEEPER_SERVER"][$hostNames[$i]] = array ( "myid" => $i+1 );
}
$db->updateHostRoleConfigs($clusterName, $hostConfig);
}
}
}
/** make sure ganglia is added to all the masters **/
$masterHosts = array();
foreach($masterToHost as $componentName=>$hostNames) {
foreach($hostNames as $hostName) {
array_push($masterHosts, $hostName);
$this->logger->log_debug("Adding host $hostName for GANGLIA_MONITOR");
}
}
$db->addHostsToComponent($clusterName, "GANGLIA_MONITOR", $masterHosts, "ASSIGNED", "");
// add DASHBOARD component
$dashhostName = strtolower(exec('hostname -f'));
$db->addHostsToComponent($clusterName, "DASHBOARD" , array($dashhostName), "ASSIGNED", "");
$slaveList = $this->getSlaveList($allHosts, $masterToHost, $services);
$this->logger->log_info("Slave List \n".print_r($slaveList, true));
$this->addSlaves($db, $slaveList, $clusterName, $services, $gangliaMaster);
/* pick a node for gateway */
$gateway = $slaveList[0];
// print_r($services);
foreach ($services as $key=>$s) {
$serviceName = $s["serviceName"];
if ($serviceName != "GANGLIA" && $serviceName != "NAGIOS" && $serviceName != "MISCELLANEOUS" && $serviceName != "DASHBOARD") {
$db->addHostsToComponent($clusterName, $serviceName."_CLIENT", array($gateway), "ASSIGNED", "");
}
}
return;
}
function excludeHMCHost($allHostsInfo) {
$result = array();
$hmcHostName = trim(strtolower(exec('hostname -f')));
foreach($allHostsInfo as $hostInfo) {
if ($hostInfo["hostName"] != $hmcHostName) {
array_push($result, $hostInfo);
}
}
$this->logger->log_debug("List for picking Nagios/Ganglia masters from \n".print_r($result, true));
return $result;
}
/**
* Function to select a list of nodes assuming
* it gets all the info from the db
* @param clustername the name of the cluster we are deploying/managing
* @param db database from where to read, usually pass in new HMCDBAccessor("mydb.data");
* @return mixed
* array (
* "result" => 0,
* "error" => "",
* "mastersToHosts" => array(
* "masterName" => array(array(
* "hostname", "totalMem")) -- this in case we have multiple hosts to suggest.
* );
*/
public function selectNodes($clustername, $db) {
$return = array();
$order = array(
array("sortColumn" => "totalMem", "sortOrder" => "DESC"),
array("sortColumn" => "cpuCount", "sortOrder" => "DESC"),
array("sortColumn" => "hostName", "sortOrder" => "ASC"),
);
$allHostsDBInfo = $db->getAllHostsInfo($clustername,
array("=" => array ( "discoveryStatus" => "SUCCESS")) , $order);
if ($allHostsDBInfo["result"] != 0) {
$this->logger->log_error("Issue getting all hosts info ".$allHostsDBInfo["error"]);
$return["result"] = $allHostsDBInfo["result"];
$return ["error"] = $allHostsDBInfo["error"];
return $return;
}
$allHostsInfo = $allHostsDBInfo["hosts"];
$numNodes = sizeof($allHostsInfo);
$this->logger->log_info("Size of Cluster ".$numNodes);
$servicesDBInfo = $db->getAllServicesInfo($clustername);
if ($servicesDBInfo["result"] != 0) {
$this->logger->log_error("Issue getting all services enabled ".$allHostsDBInfo["error"]);
$return["result"] = $servicesDBInfo["result"];
$return["error"] = $servicesDBInfo["error"];
return $return;
}
$services_tmp = $servicesDBInfo["services"];
$services = $this->filterEnabledServices($services_tmp);
$numServices = sizeof($services);
$result["result"] = 0;
$this->logger->log_debug(print_r($allHostsDBInfo, true));
$this->logger->log_debug(print_r($services,true));
// logic to avoid installing Nagios/Ganglia Master on the HMC node...
// commented out for now
//$thisHostName = trim(strtolower(exec('hostname -f')));
//$monitorIndex = ($thisHostName != $allHostsInfo[0]['hostName']) ? 0 : 1;
$monitorIndex = 0;
$allHostsInfoExHMC = $this->excludeHMCHost($allHostsInfo);
$this->logger->log_debug('num nodes='.$numNodes);
if ( $numNodes == 1 ) {
$result = $this->addNameNode($services, $result, $allHostsInfo[0]);
$result = $this->addSNameNode($services, $result, $allHostsInfo[0]);
$result = $this->addJobTracker($services, $result, $allHostsInfo[0]);
$result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
$result = $this->addOozieServer($services, $result, $allHostsInfo[0]);
$result = $this->addHiveServer($services, $result, $allHostsInfo[0]);
$result = $this->addTempletonServer($services, $result, $allHostsInfo[0]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
$result = $this->addGangliaServer($result, $allHostsInfo[0]);
$result = $this->addNagiosServer($result, $allHostsInfo[0]);
return $result;
}
if ( $numNodes < 3) {
$result = $this->addNameNode($services, $result, $allHostsInfo[0]);
$result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
$result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
$result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
$result = $this->addOozieServer($services, $result, $allHostsInfo[1]);
$result = $this->addHiveServer($services, $result, $allHostsInfo[1]);
$result = $this->addTempletonServer($services, $result, $allHostsInfo[1]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
$result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
$result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
return $result;
}
if ( $numNodes <= 5) {
$result = $this->addNameNode($services, $result, $allHostsInfo[0]);
$result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
$result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
$result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
$result = $this->addOozieServer($services, $result, $allHostsInfo[1]);
$result = $this->addHiveServer($services, $result, $allHostsInfo[1]);
$result = $this->addTempletonServer($services, $result, $allHostsInfo[1]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[1]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[2]);
$result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
$result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
return $result;
}
if ( $numNodes <= 30) {
$result = $this->addNameNode($services, $result, $allHostsInfo[0]);
$result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
$result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
$result = $this->addHBaseMaster($services, $result, $allHostsInfo[2]);
$result = $this->addOozieServer($services, $result, $allHostsInfo[2]);
$result = $this->addHiveServer($services, $result, $allHostsInfo[2]);
$result = $this->addTempletonServer($services, $result, $allHostsInfo[2]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[1]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[2]);
$result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
$result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
return $result;
}
if ( $numNodes > 30) {
$result = $this->addNameNode($services, $result, $allHostsInfo[0]);
$result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
$result = $this->addJobTracker($services, $result, $allHostsInfo[2]);
$result = $this->addHBaseMaster($services, $result, $allHostsInfo[3]);
$result = $this->addOozieServer($services, $result, $allHostsInfo[3]);
$result = $this->addHiveServer($services, $result, $allHostsInfo[4]);
$result = $this->addTempletonServer($services, $result, $allHostsInfo[4]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[1]);
$result = $this->addZooKeeperServer($services, $result, $allHostsInfo[2]);
$result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
$result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
return $result;
}
}
}
?>