selectNodes.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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("hostNames" => array($hostInfo["hostName"]));
  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. * Helper function to add ZooKeeper master server.
  110. */
  111. function addZooKeeperServer($serviceInfo, $result, $hostInfo) {
  112. if (array_key_exists("ZOOKEEPER", $serviceInfo)) {
  113. if (array_key_exists("ZOOKEEPER_SERVER", $result["mastersToHosts"])) {
  114. array_push($result["mastersToHosts"]["ZOOKEEPER_SERVER"]["hostNames"],
  115. $hostInfo["hostName"]);
  116. } else {
  117. $result["mastersToHosts"]["ZOOKEEPER_SERVER"] = $this->createHostMap($hostInfo);
  118. }
  119. }
  120. return $result;
  121. }
  122. /**
  123. * Helper function to add Ganglia master server.
  124. */
  125. function addGangliaServer($result, $hostInfo) {
  126. $result["mastersToHosts"]["GANGLIA_MONITOR_SERVER"] = $this->createHostMap($hostInfo);
  127. return $result;
  128. }
  129. /**
  130. * Helper function to add Nagios server.
  131. */
  132. function addNagiosServer($result, $hostInfo) {
  133. $result["mastersToHosts"]["NAGIOS_SERVER"] = $this->createHostMap($hostInfo);
  134. return $result;
  135. }
  136. /**
  137. * Adds all the slaves to the hostlist given whats enabled
  138. */
  139. function addSlaves($db, $hostlist, $clusterName, $services, $gangliaMaster) {
  140. $db->addHostsToComponent($clusterName, "TASKTRACKER", $hostlist, "ASSIGNED", "");
  141. $db->addHostsToComponent($clusterName, "DATANODE", $hostlist, "ASSIGNED", "");
  142. if (array_key_exists("HBASE", $services)) {
  143. $db->addHostsToComponent($clusterName, "HBASE_REGIONSERVER", $hostlist, "ASSIGNED", "");
  144. }
  145. if (array_key_exists("GANGLIA", $services)) {
  146. $hosts = $this->getExcludeHosts($hostlist, array($gangliaMaster));
  147. if (sizeof($hosts) > 0) {
  148. $db->addHostsToComponent($clusterName, "GANGLIA_MONITOR", $hosts, "ASSIGNED", "");
  149. }
  150. }
  151. }
  152. /**
  153. * Return a list of hosts excluding the ones in
  154. * $excludeHosts
  155. */
  156. function getExcludeHosts($allHosts, $excludeHosts) {
  157. $result = array();
  158. $found = FALSE;
  159. foreach ($allHosts as $host) {
  160. foreach($excludeHosts as $exclude) {
  161. if ($host == $exclude) {
  162. $found = TRUE;
  163. break;
  164. }
  165. $found = FALSE;
  166. }
  167. if (!$found) {
  168. array_push($result, $host);
  169. }
  170. }
  171. return $result;
  172. }
  173. /**
  174. * Return a list of slaves given what machines
  175. * masters are running on given the set of all host
  176. * and services enabled.
  177. */
  178. function getSlaveList($allHosts, $masterToHost, $services) {
  179. $result = array();
  180. $numNodes = sizeof($allHosts);
  181. if ($numNodes == 1) {
  182. array_push($result, $allHosts[0]);
  183. return $result;
  184. }
  185. if ($numNodes <= 5) {
  186. /* all slaves except for the namenode */
  187. $excludeList = $this->getExcludeHosts($allHosts, array($masterToHost["NAMENODE"]));
  188. return $excludeList;
  189. }
  190. if ($numNodes > 5) {
  191. /* all slaves except for the namenode/JT/Hbase master */
  192. $excludeHosts = array();
  193. array_push($excludeHosts, $masterToHost["NAMENODE"]);
  194. array_push($excludeHosts, $masterToHost["JOBTRACKER"]);
  195. if (array_key_exists("HBASE", $services)) {
  196. array_push($excludeHosts, $masterToHost["HBASE_MASTER"]);
  197. }
  198. $excludeList = $this->getExcludeHosts($allHosts, $excludeHosts);
  199. return $excludeList;
  200. }
  201. }
  202. /**
  203. * convert hostInfo to a flat list
  204. */
  205. function convertHostInfoToList($hostsInfo) {
  206. $result = array();
  207. foreach($hostsInfo as $host) {
  208. array_push($result, $host["hostName"]);
  209. }
  210. return $result;
  211. }
  212. /**
  213. * Function to update the DB with roles on what user has selected.
  214. * This also selects the DataNodes/TaskTrackers/RegionServers based
  215. * on what services were picked.
  216. * @return Error or not
  217. * array("result" => $result, "error" => $error)
  218. * @param clusterName name of the cluster
  219. * @param db the database being used
  220. * @param masterToHost the master to Host mapping that the user selected
  221. * array("componentName" => hostName")
  222. */
  223. public function updateDBWithRoles($clusterName, $db, $masterToHost) {
  224. $return = array();
  225. $return["result"] = 0;
  226. $return["error"] = "";
  227. $this->logger->log_error("All info: ".$clusterName."\n "
  228. .json_encode($masterToHost));
  229. $allHostsDBInfo = $db->getAllHostsInfo($clusterName,
  230. array("=" => array ( "discoveryStatus" => "SUCCESS")), array());
  231. if ($allHostsDBInfo["result"] != 0) {
  232. $this->logger->log_error("Issue getting all hosts info ".$allHostsDBInfo["error"]);
  233. $return["result"] = $allHostsDBInfo["result"];
  234. $return["error"] = $allHostsDBInfo["error"];
  235. return $return;
  236. }
  237. $allHosts_t = $allHostsDBInfo["hosts"];
  238. /* get all enabled services */
  239. $servicesDBInfo = $db->getAllServicesInfo($clusterName);
  240. if ($servicesDBInfo["result"] != 0) {
  241. $this->logger->log_error("Issue getting all services enabled ".$allHostsDBInfo["error"]);
  242. $return["result"] = $servicesDBInfo["result"];
  243. $return["error"] = $servicesDBInfo["error"];
  244. return $return;
  245. }
  246. $services_tmp = $servicesDBInfo["services"];
  247. $services = $this->filterEnabledServices($services_tmp);
  248. $allHosts = $this->convertHostInfoToList($allHosts_t);
  249. foreach($masterToHost as $componentName=>$hostNames) {
  250. $this->logger->log_debug("For cluster $clusterName setting $componentName to host $hostName");
  251. $db->addHostsToComponent($clusterName, $componentName, $hostNames, "ASSIGNED", "");
  252. if ($componentName == "GANGLIA_MONITOR_SERVER") {
  253. $gangliaMaster = $hostName;
  254. }
  255. }
  256. /** make sure ganglia is added to all the masters **/
  257. $this->logger->log_debug("Host for Gangalia Master $gangliaMaster");
  258. foreach($masterToHost as $componentName=>$hostName) {
  259. if ($hostName != $gangliaMaster) {
  260. $this->logger->log_debug("Adding host $hostName for GANGLIA_MONITOR");
  261. $db->addHostsToComponent($clusterName, "GANGLIA_MONITOR", array($hostName), "ASSIGNED", "");
  262. }
  263. }
  264. // add DASHBOARD component
  265. $dashhostName = strtolower(exec('hostname -f'));
  266. $db->addHostsToComponent($clusterName, "DASHBOARD" , array($dashhostName), "ASSIGNED", "");
  267. $slaveList = $this->getSlaveList($allHosts, $masterToHost, $services);
  268. $this->logger->log_info("Slave List \n".print_r($slaveList, true));
  269. $this->addSlaves($db, $slaveList, $clusterName, $services, $gangliaMaster);
  270. /* pick a node for gateway */
  271. $gateway = $slaveList[0];
  272. // print_r($services);
  273. foreach ($services as $key=>$s) {
  274. $serviceName = $s["serviceName"];
  275. if ($serviceName != "GANGLIA" && $serviceName != "NAGIOS" && $serviceName != "MISCELLANEOUS" && $serviceName != "DASHBOARD") {
  276. $db->addHostsToComponent($clusterName, $serviceName."_CLIENT", array($gateway), "ASSIGNED", "");
  277. }
  278. }
  279. return;
  280. }
  281. function excludeHMCHost($allHostsInfo) {
  282. $result = array();
  283. $hmcHostName = trim(strtolower(exec('hostname -f')));
  284. foreach($allHostsInfo as $hostInfo) {
  285. if ($hostInfo["hostName"] != $hmcHostName) {
  286. array_push($result, $hostInfo);
  287. }
  288. }
  289. $this->logger->log_debug("Excluding hmc host \n".print_r($result, true));
  290. return $result;
  291. }
  292. /**
  293. * Function to select a list of nodes assuming
  294. * it gets all the info from the db
  295. * @param clustername the name of the cluster we are deploying/managing
  296. * @param db database from where to read, usually pass in new HMCDBAccessor("mydb.data");
  297. * @return mixed
  298. * array (
  299. * "result" => 0,
  300. * "error" => "",
  301. * "mastersToHosts" => array(
  302. * "masterName" => array(array(
  303. * "hostname", "totalMem")) -- this in case we have multiple hosts to suggest.
  304. * );
  305. */
  306. public function selectNodes($clustername, $db) {
  307. $return = array();
  308. $order = array(
  309. array("sortColumn" => "totalMem", "sortOrder" => "DESC"),
  310. array("sortColumn" => "cpuCount", "sortOrder" => "DESC"),
  311. array("sortColumn" => "hostName", "sortOrder" => "ASC"),
  312. );
  313. $allHostsDBInfo = $db->getAllHostsInfo($clustername,
  314. array("=" => array ( "discoveryStatus" => "SUCCESS")) , $order);
  315. if ($allHostsDBInfo["result"] != 0) {
  316. $this->logger->log_error("Issue getting all hosts info ".$allHostsDBInfo["error"]);
  317. $return["result"] = $allHostsDBInfo["result"];
  318. $return ["error"] = $allHostsDBInfo["error"];
  319. return $return;
  320. }
  321. $allHostsInfo = $allHostsDBInfo["hosts"];
  322. $numNodes = sizeof($allHostsInfo);
  323. $this->logger->log_info("Size of Cluster ".$numNodes);
  324. $servicesDBInfo = $db->getAllServicesInfo($clustername);
  325. if ($servicesDBInfo["result"] != 0) {
  326. $this->logger->log_error("Issue getting all services enabled ".$allHostsDBInfo["error"]);
  327. $return["result"] = $servicesDBInfo["result"];
  328. $return["error"] = $servicesDBInfo["error"];
  329. return $return;
  330. }
  331. $services_tmp = $servicesDBInfo["services"];
  332. $services = $this->filterEnabledServices($services_tmp);
  333. $numServices = sizeof($services);
  334. $result["result"] = 0;
  335. $this->logger->log_debug(print_r($allHostsDBInfo, true));
  336. $this->logger->log_debug(print_r($services,true));
  337. // logic to avoid installing Nagios/Ganglia Master on the HMC node...
  338. // commented out for now
  339. //$thisHostName = trim(strtolower(exec('hostname -f')));
  340. //$monitorIndex = ($thisHostName != $allHostsInfo[0]['hostName']) ? 0 : 1;
  341. $monitorIndex = 0;
  342. $allHostsInfoExHMC = $this->excludeHMCHost($allHostsInfo);
  343. $this->logger->log_debug('num nodes='.$numNodes);
  344. if ( $numNodes == 1 ) {
  345. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  346. $result = $this->addSNameNode($services, $result, $allHostsInfo[0]);
  347. $result = $this->addJobTracker($services, $result, $allHostsInfo[0]);
  348. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
  349. $result = $this->addOozieServer($services, $result, $allHostsInfo[0]);
  350. $result = $this->addHiveServer($services, $result, $allHostsInfo[0]);
  351. $result = $this->addTempletonServer($services, $result, $allHostsInfo[0]);
  352. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
  353. $result = $this->addGangliaServer($result, $allHostsInfo[0]);
  354. $result = $this->addNagiosServer($result, $allHostsInfo[0]);
  355. return $result;
  356. }
  357. if ( $numNodes < 3) {
  358. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  359. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  360. $result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
  361. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
  362. $result = $this->addOozieServer($services, $result, $allHostsInfo[1]);
  363. $result = $this->addHiveServer($services, $result, $allHostsInfo[1]);
  364. $result = $this->addTempletonServer($services, $result, $allHostsInfo[1]);
  365. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
  366. $result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
  367. $result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
  368. return $result;
  369. }
  370. if ( $numNodes <= 5) {
  371. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  372. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  373. $result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
  374. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[0]);
  375. $result = $this->addOozieServer($services, $result, $allHostsInfo[1]);
  376. $result = $this->addHiveServer($services, $result, $allHostsInfo[1]);
  377. $result = $this->addTempletonServer($services, $result, $allHostsInfo[1]);
  378. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
  379. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[1]);
  380. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[2]);
  381. $result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
  382. $result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
  383. return $result;
  384. }
  385. if ( $numNodes <= 30) {
  386. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  387. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  388. $result = $this->addJobTracker($services, $result, $allHostsInfo[1]);
  389. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[2]);
  390. $result = $this->addOozieServer($services, $result, $allHostsInfo[2]);
  391. $result = $this->addHiveServer($services, $result, $allHostsInfo[2]);
  392. $result = $this->addTempletonServer($services, $result, $allHostsInfo[2]);
  393. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
  394. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[1]);
  395. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[2]);
  396. $result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
  397. $result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
  398. return $result;
  399. }
  400. if ( $numNodes > 30) {
  401. $result = $this->addNameNode($services, $result, $allHostsInfo[0]);
  402. $result = $this->addSNameNode($services, $result, $allHostsInfo[1]);
  403. $result = $this->addJobTracker($services, $result, $allHostsInfo[2]);
  404. $result = $this->addHBaseMaster($services, $result, $allHostsInfo[3]);
  405. $result = $this->addOozieServer($services, $result, $allHostsInfo[3]);
  406. $result = $this->addHiveServer($services, $result, $allHostsInfo[4]);
  407. $result = $this->addTempletonServer($services, $result, $allHostsInfo[4]);
  408. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[0]);
  409. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[1]);
  410. $result = $this->addZooKeeperServer($services, $result, $allHostsInfo[2]);
  411. $result = $this->addGangliaServer($result, $allHostsInfoExHMC[$monitorIndex]);
  412. $result = $this->addNagiosServer($result, $allHostsInfoExHMC[$monitorIndex]);
  413. return $result;
  414. }
  415. }
  416. }
  417. ?>