ืื™ืš ืœื”ื›ื™ืŸ ืื•ื˜ื•scaler ืžืฉืœืš ืœืืฉื›ื•ืœ

ืฉืœื•ื! ืื ื• ืžืืžื ื™ื ืื ืฉื™ื ืœืขื‘ื•ื“ ืขื ื‘ื™ื’ ื“ืื˜ื”. ืื™ ืืคืฉืจ ืœื“ืžื™ื™ืŸ ืชื•ื›ื ื™ืช ื—ื™ื ื•ื›ื™ืช ื‘ื ื•ืฉื ื‘ื™ื’ ื“ืื˜ื” ื‘ืœื™ ืืฉื›ื•ืœ ืžืฉืœื”, ืฉืขืœื™ื• ืขื•ื‘ื“ื™ื ื™ื—ื“ ื›ืœ ื”ืžืฉืชืชืคื™ื. ืžืกื™ื‘ื” ื–ื•, ืœืชื•ื›ื ื™ืช ืฉืœื ื• ื™ืฉ ืืช ื–ื” ืชืžื™ื“ ๐Ÿ™‚ ืื ื—ื ื• ืขื•ืกืงื™ื ื‘ืชืฆื•ืจื”, ื›ื•ื•ื ื•ืŸ ื•ื ื™ื”ื•ืœ ืฉืœื”, ื•ื”ื—ื‘ืจ'ื” ืžืฉื™ืงื™ื ืฉื ื™ืฉื™ืจื•ืช ืžืฉืจื•ืช MapReduce ื•ืžืฉืชืžืฉื™ื ื‘-Spark.

ื‘ืคื•ืกื˜ ื–ื” ื ืกืคืจ ืœื›ื ื›ื™ืฆื“ ืคืชืจื ื• ืืช ื‘ืขื™ื™ืช ื˜ืขื™ื ืช ื”ืืฉื›ื•ืœื•ืช ื”ืœื ืื—ื™ื“ื” ืขืœ ื™ื“ื™ ื›ืชื™ื‘ืช ื”-autoscaler ืฉืœื ื• ื‘ืืžืฆืขื•ืช ื”ืขื ืŸ ืคืชืจื•ื ื•ืช ืขื ืŸ ืฉืœ Mail.ru.

ื‘ืขื™ื”

ื”ืืฉื›ื•ืœ ืฉืœื ื• ืื™ื ื• ื‘ืฉื™ืžื•ืฉ ื‘ืžืฆื‘ ื˜ื™ืคื•ืกื™. ื”ืกื™ืœื•ืง ื”ื•ื ืžืื•ื“ ืœื ืื—ื™ื“. ืœืžืฉืœ, ื™ืฉ ืฉื™ืขื•ืจื™ื ืžืขืฉื™ื™ื, ื›ืืฉืจ ื›ืœ 30 ื”ืื ืฉื™ื ื•ืžื•ืจื” ื”ื•ืœื›ื™ื ืœืืฉื›ื•ืœ ื•ืžืชื—ื™ืœื™ื ืœื”ืฉืชืžืฉ ื‘ื•. ืื• ืฉื•ื‘, ื™ืฉ ื™ืžื™ื ืœืคื ื™ ื”ืžื•ืขื“ ืฉื‘ื• ื”ืขื•ืžืก ื’ื“ืœ ืžืื•ื“. ื‘ืฉืืจ ื”ื–ืžืŸ ื”ืืฉื›ื•ืœ ืคื•ืขืœ ื‘ืžืฆื‘ ืชืช ืขื•ืžืก.

ืคืชืจื•ืŸ ืžืก' 1 ื”ื•ื ืœืฉืžื•ืจ ืขืœ ืืฉื›ื•ืœ ืฉื™ืขืžื•ื“ ื‘ืขื•ืžืกื™ ืฉื™ื, ืื‘ืœ ื™ื”ื™ื” ืคืขื™ืœ ื‘ืฉืืจ ื”ื–ืžืŸ.

ืคืชืจื•ืŸ ืžืก' 2 ื”ื•ื ืœืฉืžื•ืจ ืขืœ ืืฉื›ื•ืœ ืงื˜ืŸ, ืืœื™ื• ืืชื” ืžื•ืกื™ืฃ ื™ื“ื ื™ืช ืฆืžืชื™ื ืœืคื ื™ ืฉื™ืขื•ืจื™ื ื•ื‘ืžื”ืœืš ืขื•ืžืกื™ ืฉื™ื.

ืคืชืจื•ืŸ ืžืก' 3 ื”ื•ื ืœืฉืžื•ืจ ืขืœ ืืฉื›ื•ืœ ืงื˜ืŸ ื•ืœื›ืชื•ื‘ ืื•ื˜ื•ืกืงืืœืจ ืฉื™ื ื˜ืจ ืืช ื”ืขื•ืžืก ื”ื ื•ื›ื—ื™ ืฉืœ ื”ืืฉื›ื•ืœ, ื•ื‘ืืžืฆืขื•ืช ืžืžืฉืงื™ API ืฉื•ื ื™ื, ืœื”ื•ืกื™ืฃ ื•ืœื”ืกื™ืจ ืฆืžืชื™ื ืžื”ืืฉื›ื•ืœ.

ื‘ืคื•ืกื˜ ื”ื–ื” ื ื“ื‘ืจ ืขืœ ืคืชืจื•ืŸ ืžืก' 3. ื”-autoscaler ื”ื–ื” ืชืœื•ื™ ืžืื•ื“ ื‘ื’ื•ืจืžื™ื ื—ื™ืฆื•ื ื™ื™ื ื•ืœื ืคื ื™ืžื™ื™ื, ื•ืœืขื™ืชื™ื ืกืคืงื™ื ืœื ืžืกืคืงื™ื ืื•ืชื•. ืื ื• ืžืฉืชืžืฉื™ื ื‘ืชืฉืชื™ืช ื”ืขื ืŸ ืฉืœ Mail.ru Cloud Solutions ื•ื›ืชื‘ื ื• ื’ื•ื“ืœ ืื•ื˜ื•ืžื˜ื™ ื‘ืืžืฆืขื•ืช ื”-API ืฉืœ MCS. ื•ืžื›ื™ื•ื•ืŸ ืฉืื ื—ื ื• ืžืœืžื“ื™ื ืื™ืš ืœืขื‘ื•ื“ ืขื ื ืชื•ื ื™ื, ื”ื—ืœื˜ื ื• ืœื”ืจืื•ืช ืื™ืš ืืชื” ื™ื›ื•ืœ ืœื›ืชื•ื‘ ืื•ื˜ื•ืกืงื™ืœืจ ื“ื•ืžื” ืœืžื˜ืจื•ืช ืฉืœืš ื•ืœื”ืฉืชืžืฉ ื‘ื• ืขื ื”ืขื ืŸ ืฉืœืš

ืชื ืื™ื ืžื•ืงื“ืžื™ื

ืจืืฉื™ืช, ืขืœื™ืš ืœื”ื™ื•ืช ื‘ืขืœ ืืฉื›ื•ืœ Hadoop. ืœื“ื•ื’ืžื”, ืื ื• ืžืฉืชืžืฉื™ื ื‘ื”ืคืฆืช HDP.

ืขืœ ืžื ืช ืฉื”ืฆืžืชื™ื ืฉืœืš ื™ื•ืกื™ืคื• ื•ื™ื•ืกืจื• ื‘ืžื”ื™ืจื•ืช, ื—ื™ื™ื‘ืช ืœื”ื™ื•ืช ืœืš ื—ืœื•ืงื” ืžืกื•ื™ืžืช ืฉืœ ืชืคืงื™ื“ื™ื ื‘ื™ืŸ ื”ืฆืžืชื™ื.

  1. ืฆื•ืžืช ืžืืกื˜ืจ. ื•ื‘ื›ืŸ, ืื™ืŸ ืฆื•ืจืš ืœื”ืกื‘ื™ืจ ืฉื•ื ื“ื‘ืจ ื‘ืžื™ื•ื—ื“: ื”ืฆื•ืžืช ื”ืจืืฉื™ ืฉืœ ื”ืืฉื›ื•ืœ, ืฉื‘ื•, ืœืžืฉืœ, ืžื•ืคืขืœ ืžื ื”ืœ ื”ื”ืชืงืŸ Spark, ืื ืืชื” ืžืฉืชืžืฉ ื‘ืžืฆื‘ ื”ืื™ื ื˜ืจืืงื˜ื™ื‘ื™.
  2. ืฆื•ืžืช ืชืืจื™ืš. ื–ื”ื• ื”ืฆื•ืžืช ืฉื‘ื• ืืชื” ืžืื—ืกืŸ ื ืชื•ื ื™ื ื‘-HDFS ื•ืฉื ืžืชื‘ืฆืขื™ื ื—ื™ืฉื•ื‘ื™ื.
  3. ืฆื•ืžืช ืžื—ืฉื•ื‘. ื–ื”ื• ืฆื•ืžืช ืฉื‘ื• ืืชื” ืœื ืžืื—ืกืŸ ืฉื•ื ื“ื‘ืจ ื‘-HDFS, ืืœื ืฉื‘ื• ืžืชืจื—ืฉื™ื ื—ื™ืฉื•ื‘ื™ื.

ื ืงื•ื“ื” ื—ืฉื•ื‘ื”. ืงื ื” ืžื™ื“ื” ืื•ื˜ื•ืžื˜ื™ ื™ืชืจื—ืฉ ืขืงื‘ ืฆืžืชื™ื ืžื”ืกื•ื’ ื”ืฉืœื™ืฉื™. ืื ืชืชื—ื™ืœ ืœืงื—ืช ื•ืœื”ื•ืกื™ืฃ ืฆืžืชื™ื ืžื”ืกื•ื’ ื”ืฉื ื™, ืžื”ื™ืจื•ืช ื”ืชื’ื•ื‘ื” ืชื”ื™ื” ื ืžื•ื›ื” ืžืื•ื“ - ื‘ื™ื˜ื•ืœ ื•ื‘ื™ืฆื•ืข ืžื—ื“ืฉ ื™ื™ืงื— ืฉืขื•ืช ืขืœ ื”ืืฉื›ื•ืœ ืฉืœืš. ื–ื”, ื›ืžื•ื‘ืŸ, ืœื ืžื” ืฉืืชื” ืžืฆืคื” ืžืฉื™ื ื•ื™ ืงื ื” ืžื™ื“ื” ืื•ื˜ื•ืžื˜ื™. ื›ืœื•ืžืจ, ืื ื—ื ื• ืœื ื ื•ื’ืขื™ื ื‘ืฆืžืชื™ื ืžื”ืกื•ื’ ื”ืจืืฉื•ืŸ ื•ื”ืฉื ื™. ื”ื ื™ื™ืฆื’ื• ืืฉื›ื•ืœ ืžื™ื ื™ืžืœื™ ื‘ืจ-ืงื™ื™ืžื ืฉื™ืชืงื™ื™ื ืœืื•ืจืš ื›ืœ ืžืฉืš ื”ืชื•ื›ื ื™ืช.

ืื–, ื”-autoscaler ืฉืœื ื• ื›ืชื•ื‘ ื‘-Python 3, ืžืฉืชืžืฉ ื‘-Ambari API ืœื ื™ื”ื•ืœ ืฉื™ืจื•ืชื™ ืืฉื›ื•ืœื•ืช, ืžืฉืชืžืฉ API ืž-Mail.ru Cloud Solutions (MCS) ืœื”ืคืขืœื” ื•ืขืฆื™ืจื” ืฉืœ ืžื›ื•ื ื•ืช.

ืืจื›ื™ื˜ืงื˜ื•ืจืช ืคืชืจื•ื ื•ืช

  1. ะœะพะดัƒะปัŒ autoscaler.py. ื”ื•ื ืžื›ื™ืœ ืฉืœื•ืฉ ืžื—ืœืงื•ืช: 1) ืคื•ื ืงืฆื™ื•ืช ืœืขื‘ื•ื“ื” ืขื Ambari, 2) ืคื•ื ืงืฆื™ื•ืช ืœืขื‘ื•ื“ื” ืขื MCS, 3) ืคื•ื ืงืฆื™ื•ืช ื”ืงืฉื•ืจื•ืช ื™ืฉื™ืจื•ืช ืœืœื•ื’ื™ืงื” ืฉืœ ื”-autoscaler.
  2. ืชึทืกืจึดื™ื˜ observer.py. ื‘ืขื™ืงืจื• ืฉืœ ื“ื‘ืจ ื–ื” ืžื•ืจื›ื‘ ืžื—ื•ืงื™ื ืฉื•ื ื™ื: ืžืชื™ ื•ื‘ืื™ืœื• ืจื’ืขื™ื ืœืงืจื•ื ืœืคื•ื ืงืฆื™ื•ืช ื”ืื•ื˜ื•ืกืงืœืจ.
  3. ืงื•ื‘ืฅ ืชืฆื•ืจื” config.py. ื”ื•ื ืžื›ื™ืœ, ืœืžืฉืœ, ืจืฉื™ืžื” ืฉืœ ืฆืžืชื™ื ื”ืžื•ืชืจื™ื ืœืฉื™ื ื•ื™ ืงื ื” ืžื™ื“ื” ืื•ื˜ื•ืžื˜ื™ ื•ืคืจืžื˜ืจื™ื ื ื•ืกืคื™ื ื”ืžืฉืคื™ืขื™ื, ืœืžืฉืœ, ืขืœ ื›ืžื” ื–ืžืŸ ืœื—ื›ื•ืช ืžืจื’ืข ื”ื•ืกืคืช ืฆื•ืžืช ื—ื“ืฉ. ื™ืฉ ื’ื ื—ื•ืชืžื•ืช ื–ืžืŸ ืœืชื—ื™ืœืช ื”ืฉื™ืขื•ืจื™ื, ื›ืš ืฉืœืคื ื™ ื”ืžื—ืœืงื” ืžื•ืคืขืœืช ืชืฆื•ืจืช ื”ืืฉื›ื•ืœ ื”ืžืงืกื™ืžืœื™ืช ื”ืžื•ืชืจืช.

ื”ื‘ื” ื ืกืชื›ืœ ื›ืขืช ืขืœ ืคื™ืกื•ืช ื”ืงื•ื“ ื‘ืชื•ืš ืฉื ื™ ื”ืงื‘ืฆื™ื ื”ืจืืฉื•ื ื™ื.

1. ืžื•ื“ื•ืœ Autoscaler.py

ื›ื™ืชืช ืืžื‘ืจื™

ื›ืš ื ืจืื™ืช ืงื˜ืข ืงื•ื“ ืฉืžื›ื™ืœ ืžื—ืœืงื” Ambari:

class Ambari:
    def __init__(self, ambari_url, cluster_name, headers, auth):
        self.ambari_url = ambari_url
        self.cluster_name = cluster_name
        self.headers = headers
        self.auth = auth

    def stop_all_services(self, hostname):
        url = self.ambari_url + self.cluster_name + '/hosts/' + hostname + '/host_components/'
        url2 = self.ambari_url + self.cluster_name + '/hosts/' + hostname
        req0 = requests.get(url2, headers=self.headers, auth=self.auth)
        services = req0.json()['host_components']
        services_list = list(map(lambda x: x['HostRoles']['component_name'], services))
        data = {
            "RequestInfo": {
                "context":"Stop All Host Components",
                "operation_level": {
                    "level":"HOST",
                    "cluster_name": self.cluster_name,
                    "host_names": hostname
                },
                "query":"HostRoles/component_name.in({0})".format(",".join(services_list))
            },
            "Body": {
                "HostRoles": {
                    "state":"INSTALLED"
                }
            }
        }
        req = requests.put(url, data=json.dumps(data), headers=self.headers, auth=self.auth)
        if req.status_code in [200, 201, 202]:
            message = 'Request accepted'
        else:
            message = req.status_code
        return message

ืœืžืขืœื”, ื›ื“ื•ื’ืžื”, ืืชื” ื™ื›ื•ืœ ืœื”ืกืชื›ืœ ืขืœ ื™ื™ืฉื•ื ื”ืคื•ื ืงืฆื™ื” stop_all_services, ืฉืขื•ืฆืจ ืืช ื›ืœ ื”ืฉื™ืจื•ืชื™ื ื‘ืฆื•ืžืช ื”ืืฉื›ื•ืœ ื”ืจืฆื•ื™.

ื‘ื›ื ื™ืกื” ืœื›ื™ืชื” Ambari ืขื‘ืจืช:

  • ambari_url, ืœืžืฉืœ, ื›ืžื• 'http://localhost:8080/api/v1/clusters/',
  • cluster_name - ืฉื ื”ืืฉื›ื•ืœ ืฉืœืš ื‘ืืžื‘ืจื™,
  • headers = {'X-Requested-By': 'ambari'}
  • ื•ื‘ืคื ื™ื auth ื”ื ื” ืคืจื˜ื™ ื”ื›ื ื™ืกื” ื•ื”ืกื™ืกืžื” ืฉืœืš ืขื‘ื•ืจ Ambari: auth = ('login', 'password').

ื”ืคื•ื ืงืฆื™ื” ืขืฆืžื” ื”ื™ื ืœื ื™ื•ืชืจ ืžื›ืžื” ืฉื™ื—ื•ืช ื“ืจืš REST API ืœืืžื‘ืืจื™. ืžื ืงื•ื“ืช ืžื‘ื˜ ื”ื’ื™ื•ื ื™ืช, ืื ื• ืžืงื‘ืœื™ื ืชื—ื™ืœื” ืจืฉื™ืžื” ืฉืœ ืฉื™ืจื•ืชื™ื ืคื•ืขืœื™ื ื‘ืฆื•ืžืช, ื•ืœืื—ืจ ืžื›ืŸ ืžื‘ืงืฉื™ื ื‘ืืฉื›ื•ืœ ื ืชื•ืŸ, ื‘ืฆื•ืžืช ื ืชื•ืŸ, ืœื”ืขื‘ื™ืจ ืฉื™ืจื•ืชื™ื ืžื”ืจืฉื™ืžื” ืœืžื“ื™ื ื” INSTALLED. ืคื•ื ืงืฆื™ื•ืช ืœื”ืคืขืœืช ื›ืœ ื”ืฉื™ืจื•ืชื™ื, ืœื”ืขื‘ืจืช ืฆืžืชื™ื ืœืžืฆื‘ Maintenance ื•ื›ื•' ื ืจืื™ื ื“ื•ืžื™ื - ืืœื• ืจืง ื›ืžื” ื‘ืงืฉื•ืช ื“ืจืš ื”-API.

ืžื—ืœืงื” ืžืง'

ื›ืš ื ืจืื™ืช ืงื˜ืข ืงื•ื“ ืฉืžื›ื™ืœ ืžื—ืœืงื” Mcs:

class Mcs:
    def __init__(self, id1, id2, password):
        self.id1 = id1
        self.id2 = id2
        self.password = password
        self.mcs_host = 'https://infra.mail.ru:8774/v2.1'

    def vm_turn_on(self, hostname):
        self.token = self.get_mcs_token()
        host = self.hostname_to_vmname(hostname)
        vm_id = self.get_vm_id(host)
        mcs_url1 = self.mcs_host + '/servers/' + self.vm_id + '/action'
        headers = {
            'X-Auth-Token': '{0}'.format(self.token),
            'Content-Type': 'application/json'
        }
        data = {'os-start' : 'null'}
        mcs = requests.post(mcs_url1, data=json.dumps(data), headers=headers)
        return mcs.status_code

ื‘ื›ื ื™ืกื” ืœื›ื™ืชื” Mcs ืื ื—ื ื• ืžืขื‘ื™ืจื™ื ืืช ืžื–ื”ื” ื”ืคืจื•ื™ืงื˜ ื‘ืชื•ืš ื”ืขื ืŸ ื•ืืช ืžื–ื”ื” ื”ืžืฉืชืžืฉ, ื›ืžื• ื’ื ืืช ื”ืกื™ืกืžื” ืฉืœื•. ื‘ืชืคืงื•ื“ vm_turn_on ืื ื—ื ื• ืจื•ืฆื™ื ืœื”ืคืขื™ืœ ืืช ืื—ืช ื”ืžื›ื•ื ื•ืช. ื”ื”ื™ื’ื™ื•ืŸ ื›ืืŸ ืงืฆืช ื™ื•ืชืจ ืžืกื•ื‘ืš. ื‘ืชื—ื™ืœืช ื”ืงื•ื“ ื ืงืจืื•ืช ืฉืœื•ืฉ ืคื•ื ืงืฆื™ื•ืช ื ื•ืกืคื•ืช: 1) ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืงื‘ืœ ืืกื™ืžื•ืŸ, 2) ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื”ืžื™ืจ ืืช ืฉื ื”ืžืืจื— ืœืฉื ืฉืœ ื”ืžื›ื•ื ื” ื‘-MCS, 3) ืœืงื‘ืœ ืืช ื”ืžื–ื”ื” ืฉืœ ื”ืžื›ื•ื ื” ื”ื–ื•. ืœืื—ืจ ืžื›ืŸ, ืื ื• ืคืฉื•ื˜ ืฉื•ืœื—ื™ื ื‘ืงืฉื” ืœืคืจืกื•ื ื•ืžืคืขื™ืœื™ื ืืช ื”ืžื›ื•ื ื” ื”ื–ื•.

ื›ืš ื ืจืื™ืช ื”ืคื•ื ืงืฆื™ื” ืœื”ืฉื’ืช ืืกื™ืžื•ืŸ:

def get_mcs_token(self):
        url = 'https://infra.mail.ru:35357/v3/auth/tokens?nocatalog'
        headers = {'Content-Type': 'application/json'}
        data = {
            'auth': {
                'identity': {
                    'methods': ['password'],
                    'password': {
                        'user': {
                            'id': self.id1,
                            'password': self.password
                        }
                    }
                },
                'scope': {
                    'project': {
                        'id': self.id2
                    }
                }
            }
        }
        params = (('nocatalog', ''),)
        req = requests.post(url, data=json.dumps(data), headers=headers, params=params)
        self.token = req.headers['X-Subject-Token']
        return self.token

ื›ื™ืชืช Autoscaler

ืžื—ืœืงื” ื–ื• ืžื›ื™ืœื” ืคื•ื ืงืฆื™ื•ืช ื”ืงืฉื•ืจื•ืช ืœืœื•ื’ื™ืงื” ื”ื”ืคืขืœื” ืขืฆืžื”.

ื›ืš ื ืจืื™ืช ืงื˜ืข ืงื•ื“ ืขื‘ื•ืจ ืžื—ืœืงื” ื–ื•:

class Autoscaler:
    def __init__(self, ambari, mcs, scaling_hosts, yarn_ram_per_node, yarn_cpu_per_node):
        self.scaling_hosts = scaling_hosts
        self.ambari = ambari
        self.mcs = mcs
        self.q_ram = deque()
        self.q_cpu = deque()
        self.num = 0
        self.yarn_ram_per_node = yarn_ram_per_node
        self.yarn_cpu_per_node = yarn_cpu_per_node

    def scale_down(self, hostname):
        flag1 = flag2 = flag3 = flag4 = flag5 = False
        if hostname in self.scaling_hosts:
            while True:
                time.sleep(5)
                status1 = self.ambari.decommission_nodemanager(hostname)
                if status1 == 'Request accepted' or status1 == 500:
                    flag1 = True
                    logging.info('Decomission request accepted: {0}'.format(flag1))
                    break
            while True:
                time.sleep(5)
                status3 = self.ambari.check_service(hostname, 'NODEMANAGER')
                if status3 == 'INSTALLED':
                    flag3 = True
                    logging.info('Nodemaneger decommissioned: {0}'.format(flag3))
                    break
            while True:
                time.sleep(5)
                status2 = self.ambari.maintenance_on(hostname)
                if status2 == 'Request accepted' or status2 == 500:
                    flag2 = True
                    logging.info('Maintenance request accepted: {0}'.format(flag2))
                    break
            while True:
                time.sleep(5)
                status4 = self.ambari.check_maintenance(hostname, 'NODEMANAGER')
                if status4 == 'ON' or status4 == 'IMPLIED_FROM_HOST':
                    flag4 = True
                    self.ambari.stop_all_services(hostname)
                    logging.info('Maintenance is on: {0}'.format(flag4))
                    logging.info('Stopping services')
                    break
            time.sleep(90)
            status5 = self.mcs.vm_turn_off(hostname)
            while True:
                time.sleep(5)
                status5 = self.mcs.get_vm_info(hostname)['server']['status']
                if status5 == 'SHUTOFF':
                    flag5 = True
                    logging.info('VM is turned off: {0}'.format(flag5))
                    break
            if flag1 and flag2 and flag3 and flag4 and flag5:
                message = 'Success'
                logging.info('Scale-down finished')
                logging.info('Cooldown period has started. Wait for several minutes')
        return message

ืื ื• ืžืงื‘ืœื™ื ืฉื™ืขื•ืจื™ื ืœื›ื ื™ืกื”. Ambari ะธ Mcs, ืจืฉื™ืžื” ืฉืœ ืฆืžืชื™ื ื”ืžื•ืชืจื™ื ืœืฉื™ื ื•ื™ ืงื ื” ืžื™ื“ื”, ื•ื›ืŸ ืคืจืžื˜ืจื™ื ืฉืœ ืชืฆื•ืจืช ืฆื•ืžืช: ื–ื™ื›ืจื•ืŸ ื•ืžืขื‘ื“ ื”ืžื•ืงืฆื™ื ืœืฆื•ืžืช ื‘-YARN. ื™ืฉื ื ื’ื 2 ืคืจืžื˜ืจื™ื ืคื ื™ืžื™ื™ื q_ram, q_cpu, ืฉื”ื ืชื•ืจื™ื. ื‘ืืžืฆืขื•ืชื, ืื ื• ืžืื—ืกื ื™ื ืืช ื”ืขืจื›ื™ื ืฉืœ ืขื•ืžืก ื”ืืฉื›ื•ืœ ื”ื ื•ื›ื—ื™. ืื ืื ื• ืจื•ืื™ื ืฉื‘ืžื”ืœืš 5 ื”ื“ืงื•ืช ื”ืื—ืจื•ื ื•ืช ื”ื™ื” ืขื•ืžืก ืžื•ื’ื‘ืจ ื‘ืขืงื‘ื™ื•ืช, ืื– ื ื—ืœื™ื˜ ืฉืขืœื™ื ื• ืœื”ื•ืกื™ืฃ ืฆื•ืžืช +1 ืœืืฉื›ื•ืœ. ื”ื“ื‘ืจ ื ื›ื•ืŸ ื’ื ืœื’ื‘ื™ ืžืฆื‘ ืชืช-ื ื™ืฆื•ืœ ื”ืืฉื›ื•ืœื•ืช.

ื”ืงื•ื“ ืœืžืขืœื” ื”ื•ื ื“ื•ื’ืžื” ืœืคื•ื ืงืฆื™ื” ืฉืžืกื™ืจื” ืžื›ื•ื ื” ืžื”ืืฉื›ื•ืœ ื•ืขื•ืฆืจืช ืื•ืชื” ื‘ืขื ืŸ. ืจืืฉื™ืช ื™ืฉ ืคื™ืจื•ืง YARN Nodemanager, ื•ืื– ื”ืžืฆื‘ ื ื“ืœืง Maintenance, ืื– ืื ื—ื ื• ืขื•ืฆืจื™ื ืืช ื›ืœ ื”ืฉื™ืจื•ืชื™ื ื‘ืžื›ื•ื ื” ื•ืžื›ื‘ื™ื ืืช ื”ืžื›ื•ื ื” ื”ื•ื™ืจื˜ื•ืืœื™ืช ื‘ืขื ืŸ.

2. Script observer.py

ืงื•ื“ ืœื“ื•ื’ืžื” ืžืฉื:

if scaler.assert_up(config.scale_up_thresholds) == True:
        hostname = cloud.get_vm_to_up(config.scaling_hosts)
        if hostname != None:
            status1 = scaler.scale_up(hostname)
            if status1 == 'Success':
                text = {"text": "{0} has been successfully scaled-up".format(hostname)}
                post = {"text": "{0}".format(text)}
                json_data = json.dumps(post)
                req = requests.post(webhook, data=json_data.encode('ascii'), headers={'Content-Type': 'application/json'})
                time.sleep(config.cooldown_period*60)

ื‘ื•, ืื ื• ื‘ื•ื“ืงื™ื ื”ืื ื ื•ืฆืจื• ืชื ืื™ื ืœื”ื’ื“ืœืช ื”ืงื™ื‘ื•ืœืช ืฉืœ ื”ืืฉื›ื•ืœ ื•ื”ืื ื™ืฉ ืžื›ื•ื ื•ืช ื›ืœืฉื”ืŸ ื‘ืžื™ืœื•ืื™ื, ืžืงื‘ืœื™ื ืืช ืฉื ื”ืžืืจื— ืฉืœ ืื—ืช ืžื”ืŸ, ืžื•ืกื™ืคื™ื ืื•ืชื” ืœืืฉื›ื•ืœ ื•ืžืคืจืกืžื™ื ื”ื•ื“ืขื” ืขืœ ื›ืš ื‘-Slack ืฉืœ ื”ืฆื•ื•ืช ืฉืœื ื•. ืื—ืจื™ ื–ื” ื–ื” ืžืชื—ื™ืœ cooldown_period, ื›ืืฉืจ ืื ื—ื ื• ืœื ืžื•ืกื™ืคื™ื ืื• ืžืกื™ืจื™ื ืฉื•ื ื“ื‘ืจ ืžื”ืืฉื›ื•ืœ, ืืœื ืคืฉื•ื˜ ืขื•ืงื‘ื™ื ืื—ืจ ื”ืขื•ืžืก. ืื ื”ื•ื ื”ืชื™ื™ืฆื‘ ื•ื ืžืฆื ื‘ืžืกื“ืจื•ืŸ ืฉืœ ืขืจื›ื™ ืขื•ืžืก ืื•ืคื˜ื™ืžืœื™ื™ื, ืื– ืื ื—ื ื• ืคืฉื•ื˜ ืžืžืฉื™ื›ื™ื ื‘ืžืขืงื‘. ืื ืฆื•ืžืช ืื—ื“ ืœื ื”ืกืคื™ืง, ื ื•ืกื™ืฃ ืขื•ื“ ืื—ื“.

ืœืžืงืจื™ื ืฉื‘ื”ื ื™ืฉ ืœื ื• ืฉื™ืขื•ืจ ืœืคื ื™ื ื•, ืื ื—ื ื• ื›ื‘ืจ ื™ื•ื“ืขื™ื ื‘ื•ื•ื“ืื•ืช ืฉืฆื•ืžืช ืื—ื“ ืœื ื™ืกืคื™ืง, ืื– ืื ื—ื ื• ืžืชื—ื™ืœื™ื ืžื™ื“ ืืช ื›ืœ ื”ืฆืžืชื™ื ื”ืคื ื•ื™ื™ื ื•ืžืฉืื™ืจื™ื ืื•ืชื ืคืขื™ืœื™ื ืขื“ ืกื•ืฃ ื”ืฉื™ืขื•ืจ. ื–ื” ืงื•ืจื” ื‘ืืžืฆืขื•ืช ืจืฉื™ืžื” ืฉืœ ื—ื•ืชืžื•ืช ื–ืžืŸ ืฉืœ ืคืขื™ืœื•ืช.

ืžืกืงื ื”

Autoscaler ื”ื•ื ืคืชืจื•ืŸ ื˜ื•ื‘ ื•ื ื•ื— ืœืื•ืชื ืžืงืจื™ื ืฉื‘ื”ื ืืชื” ื—ื•ื•ื” ื˜ืขื™ื ืช ืืฉื›ื•ืœ ืœื ืื—ื™ื“ื”. ืืชื” ืžืฉื™ื’ ื‘ื• ื–ืžื ื™ืช ืืช ืชืฆื•ืจืช ื”ืืฉื›ื•ืœ ื”ืจืฆื•ื™ื” ืขื‘ื•ืจ ืขื•ืžืกื™ ืฉื™ื ื•ื‘ื• ื–ืžื ื™ืช ืœื ืฉื•ืžืจื™ื ืขืœ ืืฉื›ื•ืœ ื–ื” ื‘ื–ืžืŸ ืขื•ืžืก ื ืžื•ืš, ื•ื—ื•ืกืš ื›ืกืฃ. ื•ื‘ื›ืŸ, ื‘ื ื•ืกืฃ ื›ืœ ื–ื” ืงื•ืจื” ืื•ื˜ื•ืžื˜ื™ืช ืœืœื ื”ืฉืชืชืคื•ืชืš. ื”-autoscaler ืขืฆืžื• ื”ื•ื ืœื ื™ื•ืชืจ ืžืกื˜ ืฉืœ ื‘ืงืฉื•ืช ืœ-API ืฉืœ ืžื ื”ืœ ื”ืืฉื›ื•ืœื•ืช ื•ืœ-API ืฉืœ ืกืคืง ื”ืขื ืŸ, ืฉื ื›ืชื‘ื• ืขืœ ืคื™ ื”ื™ื’ื™ื•ืŸ ืžืกื•ื™ื. ืžื” ืฉืืชื” ื‘ื”ื—ืœื˜ ืฆืจื™ืš ืœื–ื›ื•ืจ ื”ื•ื ื—ืœื•ืงืช ื”ืฆืžืชื™ื ืœ-3 ืกื•ื’ื™ื, ื›ืคื™ ืฉื›ืชื‘ื ื• ืงื•ื“ื ืœื›ืŸ. ื•ืืชื” ืชื”ื™ื” ืžืื•ืฉืจ.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”