Переглянути джерело

AMBARI-16790: Add HAWQ Standby wizard should recommend HAWQSTANDBY correctly (mithmatt)

Matt 9 роки тому
батько
коміт
b9b7dab72b

+ 17 - 6
ambari-server/src/main/resources/common-services/HAWQ/2.0.0/service_advisor.py

@@ -17,11 +17,9 @@ See the License for the specific language governing permissions and
 limitations under the License.
 """
 import os
-import fnmatch
 import imp
 import re
 import socket
-import sys
 import traceback
 import math
 
@@ -39,10 +37,23 @@ except Exception as e:
 class HAWQ200ServiceAdvisor(service_advisor.ServiceAdvisor):
 
   def getHostsForMasterComponent(self, stackAdvisor, services, hosts, component, hostsList, hostsComponentsMap):
-    componentName = component["StackServiceComponents"]["component_name"]
+    if component["StackServiceComponents"]["component_name"] == 'HAWQSTANDBY':
+      # Do not recommend HAWQSTANDBY on single node cluster, or cluster with no active hosts
+      if len(hostsList) <= 1:
+        return []
+      
+      componentsListList = [service["components"] for service in services["services"]]
+      componentsList = [item["StackServiceComponents"] for sublist in componentsListList for item in sublist]
+      hawqMasterHosts = self.getHosts(componentsList, "HAWQMASTER")
 
-    if componentName == 'HAWQSTANDBY' and len(hostsList) == 1:
-      return []
+      # if HAWQMASTER has already been assigned, try to ensure HAWQSTANDBY is not placed on the same host
+      if len(hawqMasterHosts) > 0:
+        ambariServerHost = socket.getfqdn()
+        availableHosts = [host for host in hostsList if host not in (hawqMasterHosts[0], ambariServerHost)]
+        # Return list containing first available host if there are available hosts
+        if len(availableHosts) > 0:
+          return availableHosts[:1]
+        return [ambariServerHost]
 
     return stackAdvisor.getHostsForMasterComponent(services, hosts, component, hostsList, hostsComponentsMap)
 
@@ -315,4 +326,4 @@ class HAWQ200ServiceAdvisor(service_advisor.ServiceAdvisor):
       if message:
         validationItems.append({"config-name": PROP_NAME, "item": self.getWarnItem(message.format(PROP_NAME, str(MIN_NUM_SEGMENT_THRESHOLD)))})
 
-    return stackAdvisor.toConfigurationValidationProblems(validationItems, "hdfs-client")
+    return stackAdvisor.toConfigurationValidationProblems(validationItems, "hdfs-client")

+ 77 - 2
ambari-server/src/test/python/stacks/2.3/HAWQ/test_service_advisor.py

@@ -17,13 +17,14 @@ limitations under the License.
 """
 
 import os
+import imp
 from unittest import TestCase
+from mock.mock import patch, MagicMock
 
 
 class TestHAWQ200ServiceAdvisor(TestCase):
 
   def setUp(self):
-    import imp
     self.testDirectory = os.path.dirname(os.path.abspath(__file__))
     stackAdvisorPath = os.path.join(self.testDirectory, '../../../../../main/resources/stacks/stack_advisor.py')
     hawq200ServiceAdvisorPath = os.path.join(self.testDirectory, '../../../../../main/resources/common-services/HAWQ/2.0.0/service_advisor.py')
@@ -39,6 +40,80 @@ class TestHAWQ200ServiceAdvisor(TestCase):
     serviceAdvisorClass = getattr(service_advisor, 'HAWQ200ServiceAdvisor')
     self.serviceAdvisor = serviceAdvisorClass()
 
+
+  @patch("socket.getfqdn")
+  def test_getHostsForMasterComponent(self, getfqdn_mock):
+    getfqdn_mock.return_value = "c6401.ambari.apache.org"
+
+    services = {
+      "services": [
+        {
+          "components": [
+            {
+              "StackServiceComponents": {
+                "component_name": "HAWQMASTER",
+                "hostnames": [
+                  "c6403.ambari.apache.org"
+                ]
+              }
+            },
+            {
+              "StackServiceComponents": {
+                "component_name": "HAWQSTANDBY",
+                "hostnames": [
+                ]
+              }
+            }
+          ]
+        }
+      ]
+    }
+
+    hostsList = ["c6401.ambari.apache.org", "c6402.ambari.apache.org", "c6403.ambari.apache.org", "c6404.ambari.apache.org"]
+
+    component = {
+      "StackServiceComponents": {
+        "component_name": "HAWQSTANDBY"
+      }
+    }
+
+    # Case 1:
+    # Ambari Server is placed on c6401.ambari.apache.org
+    # HAWQMASTER is placed on c6403.ambari.apache.org
+    # There are 4 available hosts in the cluster
+    # Recommend HAWQSTANDBY on next available host, c6402.ambari.apache.org
+    standbyHosts = self.serviceAdvisor.getHostsForMasterComponent(self.stackAdvisor, services, None, component, hostsList, None)
+    self.assertEquals(standbyHosts, ["c6402.ambari.apache.org"])
+
+    # Case 2:
+    # Ambari Server is placed on c6401.ambari.apache.org
+    # HAWQMASTER is placed on c6402.ambari.apache.org
+    # There are 4 available hosts in the cluster
+    # Recommend HAWQSTANDBY on next available host, c6403.ambari.apache.org
+    services["services"][0]["components"][0]["StackServiceComponents"]["hostnames"] = ["c6402.ambari.apache.org"]
+    standbyHosts = self.serviceAdvisor.getHostsForMasterComponent(self.stackAdvisor, services, None, component, hostsList, None)
+    self.assertEquals(standbyHosts, ["c6403.ambari.apache.org"])
+
+    # Case 3:
+    # Ambari Server is placed on c6401.ambari.apache.org
+    # HAWQMASTER is placed on c6402.ambari.apache.org
+    # There are 2 available hosts in the cluster
+    # Recommend HAWQSTANDBY on a host which does not have HAWQMASTER, c6401.ambari.apache.org
+    hostsList = ["c6401.ambari.apache.org", "c6402.ambari.apache.org"]
+    standbyHosts = self.serviceAdvisor.getHostsForMasterComponent(self.stackAdvisor, services, None, component, hostsList, None)
+    self.assertEquals(standbyHosts, ["c6401.ambari.apache.org"])
+
+    # Case 4:
+    # Ambari Server is placed on c6401.ambari.apache.org
+    # HAWQMASTER is placed on c6401.ambari.apache.org
+    # There is 1 available host in the cluster
+    # Do not recommend HAWQSTANDBY on a single node cluster
+    hostsList = ["c6401.ambari.apache.org"]
+    services["services"][0]["components"][0]["StackServiceComponents"]["hostnames"] = ["c6401.ambari.apache.org"]
+    standbyHosts = self.serviceAdvisor.getHostsForMasterComponent(self.stackAdvisor, services, None, component, hostsList, None)
+    self.assertEquals(standbyHosts, [])
+
+
   def test_getServiceConfigurationRecommendations(self):
 
     configurations = {
@@ -159,4 +234,4 @@ class TestHAWQ200ServiceAdvisor(TestCase):
     hosts["items"][1]["Hosts"]["total_mem"] = 2073741824
     hosts["items"][3]["Hosts"]["total_mem"] = 3073741824
     self.serviceAdvisor.getServiceConfigurationRecommendations(self.stackAdvisor, configurations, None, services, hosts)
-    self.assertEqual(configurations["hawq-site"]["properties"]["hawq_rm_memory_limit_perseg"], "436GB")
+    self.assertEqual(configurations["hawq-site"]["properties"]["hawq_rm_memory_limit_perseg"], "436GB")