selectNodes.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <?php
  2. /*
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. class SelectNodes {
  20. private $logger;
  21. /**
  22. * Needs a default constructor else warnings will appear.
  23. */
  24. function __construct() {
  25. $this->logger = new HMCLogger("SelectNodes");
  26. }
  27. /** Helper function for creating an array for hostName and totalMem
  28. */
  29. function createHostMap($hostInfo) {
  30. $result = array("hostName" => $hostInfo["hostName"], "totalMem" => $hostInfo["totalMem"]);
  31. return $result;
  32. }
  33. /** Return only the enabled services.
  34. */
  35. function filterEnabledServices($services) {
  36. $enabledServices = array();
  37. foreach($services as $serviceName=>$serviceInfo) {
  38. if ($serviceInfo["isEnabled"] == 1) {
  39. $enabledServices[$serviceName] = $serviceInfo;
  40. }
  41. }
  42. return $enabledServices;
  43. }
  44. /**
  45. * Helper function to add HDFS NameNode
  46. */
  47. function addNameNode($serviceInfo, $result, $hostInfo) {
  48. if (array_key_exists("HDFS", $serviceInfo)) {
  49. $result["mastersToHosts"]["NAMENODE"] = $this->createHostMap($hostInfo);
  50. }
  51. $this->logger->log_info("Adding to result ".$result);
  52. return $result;
  53. }
  54. /**
  55. * Helper function to add SNameNode
  56. */
  57. function addSNameNode($serviceInfo, $result, $hostInfo) {
  58. if (array_key_exists("HDFS", $serviceInfo)) {
  59. $result["mastersToHosts"]["SNAMENODE"] = $this->createHostMap($hostInfo);
  60. }
  61. return $result;
  62. }
  63. /**
  64. * Helper function to add JobTracker.
  65. */
  66. function addJobTracker($serviceInfo, $result, $hostInfo) {
  67. if (array_key_exists("MAPREDUCE", $serviceInfo)) {
  68. $result["mastersToHosts"]["JOBTRACKER"] = $this->createHostMap($hostInfo);
  69. }
  70. return $result;
  71. }
  72. /**
  73. * Helper function to add HBase Master.
  74. */
  75. function addHBaseMaster($serviceInfo, $result, $hostInfo) {
  76. if (array_key_exists("HBASE", $serviceInfo)) {
  77. $result["mastersToHosts"]["HBASE_MASTER"] = $this->createHostMap($hostInfo);
  78. }
  79. return $result;
  80. }
  81. /**
  82. * Helper function to add Oozie server.
  83. */
  84. function addOozieServer($serviceInfo, $result, $hostInfo) {
  85. if (array_key_exists("OOZIE", $serviceInfo)) {
  86. $result["mastersToHosts"]["OOZIE_SERVER"] = $this->createHostMap($hostInfo);
  87. }
  88. return $result;
  89. }
  90. /**
  91. * Helper function to add Hive Server.
  92. */
  93. function addHiveServer($serviceInfo, $result, $hostInfo) {
  94. if (array_key_exists("HIVE", $serviceInfo)) {
  95. $result["mastersToHosts"]["HIVE_SERVER"] = $this->createHostMap($hostInfo);
  96. }
  97. return $result;
  98. }
  99. /**
  100. * Helper function to add Templeton.
  101. */
  102. function addTempletonServer($serviceInfo, $result, $hostInfo) {
  103. if (array_key_exists("TEMPLETON", $serviceInfo)) {
  104. $result["mastersToHosts"]["TEMPLETON_SERVER"] = $this->createHostMap($hostInfo);
  105. }
  106. return $result;
  107. }
  108. /**
  109. * Adds all the slaves to the hostlist given whats enabled
  110. */
  111. function addSlaves($db, $hostlist, $clusterName, $services, $gangliaMaster) {
  112. $db->addHostsToComponent($clusterName, "TASKTRACKER", $hostlist, "ASSIGNED", "");
  113. $db->addHostsToComponent($clusterName, "DATANODE", $hostlist, "ASSIGNED", "");
  114. if (array_key_exists("HBASE", $services)) {
  115. $db->addHostsToComponent($clusterName, "HBASE_REGIONSERVER", $hostlist, "ASSIGNED", "");
  116. }
  117. if (array_key_exists("GANGLIA", $services)) {
  118. $hosts = $this->getExcludeHosts($hostlist, array($gangliaMaster));
  119. if (sizeof($hosts) > 0) {
  120. $db->addHostsToComponent($clusterName, "GANGLIA_MONITOR", $hosts, "ASSIGNED", "");
  121. }
  122. }
  123. }
  124. /**
  125. * Return a list of hosts excluding the ones in
  126. * $excludeHosts
  127. */
  128. function getExcludeHosts($allHosts, $excludeHosts) {
  129. $result = array();
  130. $found = FALSE;
  131. foreach ($allHosts as $host) {
  132. foreach($excludeHosts as $exclude) {
  133. if ($host == $exclude) {
  134. $found = TRUE;
  135. break;
  136. }
  137. $found = FALSE;
  138. }
  139. if (!$found) {
  140. array_push($result, $host);
  141. }
  142. }
  143. return $result;
  144. }
  145. /**
  146. * Return a list of slaves given what machines
  147. * masters are running on given the set of all host
  148. * and services enabled.
  149. */
  150. function getSlaveList($allHosts, $masterToHost, $services) {
  151. $result = array();
  152. $numNodes = sizeof($allHosts);
  153. if ($numNodes == 1) {
  154. array_push($result, $allHosts[0]);
  155. return $result;
  156. }
  157. if ($numNodes <= 5) {
  158. /* all slaves except for the namenode */
  159. $excludeList = $this->getExcludeHosts($allHosts, array($masterToHost["NAMENODE"]));
  160. return $excludeList;
  161. }
  162. if ($numNodes > 5) {
  163. /* all slaves except for the namenode/JT/Hbase master */
  164. $excludeHosts = array();
  165. array_push($excludeHosts, $masterToHost["NAMENODE"]);
  166. array_push($excludeHosts, $masterToHost["JOBTRACKER"]);
  167. if (array_key_exists("HBASE", $services)) {
  168. array_push($excludeHosts, $masterToHost["HBASE_MASTER"]);
  169. }
  170. $excludeList = $this->getExcludeHosts($allHosts, $excludeHosts);
  171. return $excludeList;
  172. }
  173. }
  174. /**
  175. * convert hostInfo to a flat list
  176. */
  177. function convertHostInfoToList($hostsInfo) {
  178. $result = array();
  179. foreach($hostsInfo as $host) {
  180. array_push($result, $host["hostName"]);
  181. }
  182. return $result;
  183. }
  184. /**
  185. * Function to update the DB with roles on what user has selected.
  186. * This also selects the DataNodes/TaskTrackers/RegionServers based
  187. * on what services were picked.
  188. * @return Error or not
  189. * array("result" => $result, "error" => $error)
  190. * @param clusterName name of the cluster
  191. * @param db the database being used
  192. * @param masterToHost the master to Host mapping that the user selected
  193. * array("componentName" => hostName")
  194. */
  195. public function updateDBWithRoles($clusterName, $db, $masterToHost) {
  196. $return = array();
  197. $return["result"] = 0;
  198. $return["error"] = "";
  199. $this->logger->log_error("All info: ".$clusterName."\n "
  200. .json_encode($masterToHost));
  201. $allHostsDBInfo = $db->getAllHostsInfo($clusterName,
  202. array("=" => array ( "discoveryStatus" => "SUCCESS")), array());
  203. if ($allHostsDBInfo["result"] != 0) {
  204. $this->logger->log_error("Issue getting all hosts info ".$allHostsDBInfo["error"]);
  205. $return["result"] = $allHostsDBInfo["result"];
  206. $return["error"] = $allHostsDBInfo["error"];
  207. return $return;
  208. }
  209. $allHosts_t = $allHostsDBInfo["hosts"];
  210. /* get all enabled services */
  211. $servicesDBInfo = $db->getAllServicesInfo($clusterName);
  212. if ($servicesDBInfo["result"] != 0) {
  213. $this->logger->log_error("Issue getting all services enabled ".$allHostsDBInfo["error"]);
  214. $return["result"] = $servicesDBInfo["result"];
  215. $return["error"] = $servicesDBInfo["error"];
  216. return $return;
  217. }
  218. $services_tmp = $servicesDBInfo["services"];
  219. $services = $this->filterEnabledServices($services_tmp);
  220. $allHosts = $this->convertHostInfoToList($allHosts_t);
  221. foreach($masterToHost as $componentName=>$hostName) {
  222. if ($componentName != "ZOOKEEPER_SERVER") {
  223. $this->logger->log_debug("For cluster $clusterName setting $componentName to host $hostName");
  224. $db->addHostsToComponent($clusterName, $componentName, array($hostName), "ASSIGNED", "");
  225. }
  226. if ($componentName == "GANGLIA_MONITOR_SERVER") {
  227. $gangliaMaster = $hostName;
  228. }
  229. }
  230. /** make sure ganglia is added to all the masters **/
  231. $this->logger->log_debug("Host for Gangalia Master $gangliaMaster");
  232. foreach($masterToHost as $componentName=>$hostName) {
  233. if ($hostName != $gangliaMaster) {
  234. $this->logger->log_debug("Adding host $hostName for GANGLIA_MONITOR");
  235. $db->addHostsToComponent($clusterName, "GANGLIA_MONITOR", array($hostName), "ASSIGNED", "");
  236. }
  237. }
  238. // add DASHBOARD component
  239. $dashhostName = strtolower(exec('hostname -f'));
  240. $db->addHostsToComponent($clusterName, "DASHBOARD" , array($dashhostName), "ASSIGNED", "");
  241. $slaveList = $this->getSlaveList($allHosts, $masterToHost, $services);
  242. if (array_key_exists("ZOOKEEPER", $services)) {
  243. if (sizeof($slaveList) < 3) {
  244. $this->logger->log_debug("Assigning ZOOKEEPER to Host ".array($slaveList[0]));
  245. $db->addHostsToComponent($clusterName, "ZOOKEEPER_SERVER", array($slaveList[0]), "ASSIGNED", "");
  246. $hostConfig = array ( "ZOOKEEPER_SERVER" => array( $slaveList[0] => array ( "myid" => 1 ) ) );
  247. $db->updateHostRoleConfigs($clusterName, $hostConfig);
  248. }
  249. else {
  250. $hostConfig = array( "ZOOKEEPER_SERVER" => array() );
  251. for ($i=0; $i < 3; $i++) {
  252. $hostConfig["ZOOKEEPER_SERVER"][$slaveList[$i]] = array ( "myid" => $i+1 );
  253. $this->logger->log_debug("Assigning ZOOKEEPER to Host ".array($slaveList[$i]));
  254. $db->addHostsToComponent($clusterName, "ZOOKEEPER_SERVER", array($slaveList[$i]), "ASSIGNED", "");
  255. }
  256. $db->updateHostRoleConfigs($clusterName, $hostConfig);
  257. }
  258. }
  259. $this->logger->log_info("Slave List \n".print_r($slaveList, true));
  260. $this->addSlaves($db, $slaveList, $clusterName, $services, $gangliaMaster);
  261. /* pick a node for gateway */
  262. $gateway = $slaveList[0];
  263. // print_r($services);
  264. foreach ($services as $key=>$s) {
  265. $serviceName = $s["serviceName"];
  266. if ($serviceName != "GANGLIA" && $serviceName != "NAGIOS" && $serviceName != "MISCELLANEOUS" && $serviceName != "DASHBOARD") {
  267. $db->addHostsToComponent($clusterName, $serviceName."_CLIENT", array($gateway), "ASSIGNED", "");
  268. }
  269. }
  270. return;
  271. }
  272. /**
  273. * Function to select a list of nodes assuming
  274. * it gets all the info from the db
  275. * @param clustername the name of the cluster we are deploying/managing
  276. * @param db database from where to read, usually pass in new HMCDBAccessor("mydb.data");
  277. * @return mixed
  278. * array (
  279. * "result" => 0,
  280. * "error" => "",
  281. * "mastersToHosts" => array(
  282. * "masterName" => array(array(
  283. * "hostname", "totalMem")) -- this in case we have multiple hosts to suggest.
  284. * );
  285. */
  286. public function selectNodes($clustername, $db) {
  287. $return = array();
  288. $order = array("sortColumn" => "totalMem",
  289. "sortOrder" => "DESC");
  290. $allHostsDBInfo = $db->getAllHostsInfo($clustername,
  291. array("=" => array ( "discoveryStatus" => "SUCCESS")) , $order);
  292. if ($allHostsDBInfo["result"] != 0) {
  293. $this->logger->log_error("Issue getting all hosts info ".$allHostsDBInfo["error"]);
  294. $return["result"] = $allHostsDBInfo["result"];
  295. $return ["error"] = $allHostsDBInfo["error"];
  296. return $return;
  297. }
  298. $allHostsInfo = $allHostsDBInfo["hosts"];
  299. $numNodes = sizeof($allHostsInfo);
  300. $this->logger->log_info("Size of Cluster ".$numNodes);
  301. $servicesDBInfo = $db->getAllServicesInfo($clustername);
  302. if ($servicesDBInfo["result"] != 0) {
  303. $this->logger->log_error("Issue getting all services enabled ".$allHostsDBInfo["error"]);
  304. $return["result"] = $servicesDBInfo["result"];
  305. $return["error"] = $servicesDBInfo["error"];
  306. return $return;
  307. }
  308. $services_tmp = $servicesDBInfo["services"];
  309. $services = $this->filterEnabledServices($services_tmp);
  310. $numServices = sizeof($services);
  311. $result["result"] = 0;
  312. $this->logger->log_debug(print_r($allHostsDBInfo, true));
  313. $this->logger->log_debug(print_r($services,true));
  314. if ($numNodes == 1) {
  315. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  316. $result = $this->addSNameNode($services, $result, $allHostsInfo[0]);
  317. $result = $this->addJobTracker($services, $result, $allHostsInfo[0]);
  318. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
  319. $result = $this->addOozieServer($services, $result, $allHostsInfo[0]);
  320. $result = $this->addHiveServer($services, $result, $allHostsInfo[0]);
  321. $result = $this->addTempletonServer($services, $result, $allHostsInfo[0]);
  322. return $result;
  323. }
  324. if ( $numNodes <= 5) {
  325. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  326. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  327. $result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
  328. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
  329. $result = $this->addOozieServer($services, $result, $allHostsInfo[1]);
  330. $result = $this->addHiveServer($services, $result, $allHostsInfo[1]);
  331. $result = $this->addTempletonServer($services, $result, $allHostsInfo[1]);
  332. return $result;
  333. }
  334. if ( $numNodes <= 30) {
  335. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  336. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  337. $result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
  338. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[2]);
  339. $result = $this->addOozieServer($services, $result, $allHostsInfo[2]);
  340. $result = $this->addHiveServer($services, $result, $allHostsInfo[2]);
  341. $result = $this->addTempletonServer($services, $result, $allHostsInfo[2]);
  342. return $result;
  343. }
  344. if ( $numNodes > 30) {
  345. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  346. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  347. $result = $this->addJobTracker($services, $result, $allHostsInfo[2]);
  348. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[3]);
  349. $result = $this->addOozieServer($services, $result, $allHostsInfo[3]);
  350. $result = $this->addHiveServer($services, $result, $allHostsInfo[4]);
  351. $result = $this->addTempletonServer($services, $result, $allHostsInfo[4]);
  352. return $result;
  353. }
  354. }
  355. }
  356. ?>