Giunsa paghimo ang imong kaugalingon nga autoscaler alang sa usa ka cluster

Hello! Gibansay namo ang mga tawo sa pagtrabaho gamit ang dagkong datos. Imposible nga mahanduraw ang usa ka programa sa edukasyon sa dagkong datos nga wala’y kaugalingon nga kumpol, diin ang tanan nga mga partisipante nagtinabangay. Tungod niini nga hinungdan, ang among programa kanunay adunay kini 🙂 Kami nalambigit sa pag-configure, pag-tune ug pagdumala niini, ug ang mga lalaki direkta nga naglansad sa mga trabaho sa MapReduce didto ug gigamit ang Spark.

Sa kini nga post isulti namon kanimo kung giunsa namon nasulbad ang problema sa dili patas nga pagkarga sa cluster pinaagi sa pagsulat sa among kaugalingon nga autoscaler gamit ang panganod Mail.ru Cloud Solutions.

problema

Ang among cluster wala gigamit sa usa ka tipikal nga mode. Ang paglabay kay dili patas. Pananglitan, adunay mga praktikal nga klase, kung ang tanan nga 30 ka tawo ug usa ka magtutudlo moadto sa cluster ug magsugod sa paggamit niini. O pag-usab, adunay mga adlaw sa wala pa ang deadline kung ang load nagdugang pag-ayo. Ang nahabilin nga oras ang cluster naglihok sa underload mode.

Ang solusyon #1 mao ang pagpabilin sa usa ka cluster nga makasugakod sa mga peak load, apan walay trabaho sa nahabilin nga panahon.

Ang solusyon #2 mao ang pagpabilin sa usa ka gamay nga pungpong, diin imong idugang ang mga node sa wala pa ang mga klase ug sa panahon sa peak load.

Ang solusyon #3 mao ang pagtipig og gamay nga cluster ug pagsulat og autoscaler nga magmonitor sa kasamtangan nga load sa cluster ug, gamit ang lain-laing mga API, pagdugang ug pagtangtang sa mga node gikan sa cluster.

Niini nga post maghisgot kita bahin sa solusyon #3. Kini nga autoscaler nagsalig kaayo sa mga panggawas nga mga hinungdan kaysa sa mga internal, ug ang mga tighatag kanunay wala maghatag niini. Gigamit namo ang Mail.ru Cloud Solutions cloud infrastructure ug misulat ug autoscaler gamit ang MCS API. Ug tungod kay nagtudlo kami kung giunsa ang pagtrabaho sa datos, nakahukom kami nga ipakita kung giunsa nimo pagsulat ang usa ka parehas nga autoscaler alang sa imong kaugalingon nga katuyoan ug gamiton kini sa imong panganod

Kinahanglanon

Una, kinahanglan nga adunay usa ka Hadoop cluster. Pananglitan, among gigamit ang pag-apod-apod sa HDP.

Aron ang imong mga node dali nga madugang ug matangtang, kinahanglan nga adunay usa ka piho nga pag-apod-apod sa mga tahas taliwala sa mga node.

  1. Master node. Aw, dili kinahanglan nga ipasabut ang bisan unsa labi na: ang panguna nga node sa cluster, diin, pananglitan, ang drayber sa Spark gilansad, kung gigamit nimo ang interactive mode.
  2. Node sa petsa. Kini ang node diin imong gitipigan ang datos sa HDFS ug kung diin mahitabo ang mga kalkulasyon.
  3. Pag-compute sa node. Kini usa ka node diin wala ka magtipig bisan unsa sa HDFS, apan kung diin mahitabo ang mga kalkulasyon.

Importante nga punto. Ang autoscaling mahitabo tungod sa mga node sa ikatulo nga tipo. Kung magsugod ka sa pagkuha ug pagdugang sa mga node sa ikaduha nga tipo, ang katulin sa pagtubag mahimong ubos kaayo - ang pag-decommissioning ug pag-recommit magkinahanglan daghang oras sa imong cluster. Kini, siyempre, dili ang imong gipaabut gikan sa autoscaling. Sa ato pa, dili kami magtandog sa mga node sa una ug ikaduha nga mga tipo. Sila magrepresentar sa usa ka minimum nga mabuhi nga cluster nga anaa sa tibuok nga gidugayon sa programa.

Mao nga, ang among autoscaler gisulat sa Python 3, gigamit ang Ambari API sa pagdumala sa mga serbisyo sa cluster, gamit API gikan sa Mail.ru Cloud Solutions (MCS) alang sa pagsugod ug paghunong sa mga makina.

Solusyon nga arkitektura

  1. Modyul autoscaler.py. Naglangkob kini sa tulo ka mga klase: 1) mga gimbuhaton alang sa pagtrabaho kauban si Ambari, 2) mga gimbuhaton alang sa pagtrabaho kauban ang MCS, 3) mga gimbuhaton nga direktang may kalabotan sa lohika sa autoscaler.
  2. Script observer.py. Sa panguna kini naglangkob sa lainlaing mga lagda: kanus-a ug sa unsang mga higayon nga tawagan ang mga function sa autoscaler.
  3. Pag-configure nga file config.py. Naglangkob kini, pananglitan, usa ka lista sa mga node nga gitugotan alang sa autoscaling ug uban pang mga parameter nga makaapekto, pananglitan, kung unsa kadugay ang paghulat gikan sa higayon nga gidugang ang usa ka bag-ong node. Adunay usab mga timestamp alang sa pagsugod sa mga klase, aron sa wala pa ang klase ang labing kadaghan nga gitugotan nga pagsulud sa cluster gilansad.

Atong tan-awon karon ang mga piraso sa code sa sulod sa unang duha ka mga file.

1. Autoscaler.py module

Klase sa Ambari

Kini ang hitsura sa usa ka piraso sa code nga adunay usa ka klase 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

Sa ibabaw, isip usa ka pananglitan, mahimo nimong tan-awon ang pagpatuman sa function stop_all_services, nga nagpahunong sa tanang serbisyo sa gusto nga cluster node.

Sa entrada sa klase Ambari pasado ka:

  • ambari_url, pananglitan, sama sa 'http://localhost:8080/api/v1/clusters/',
  • cluster_name – ang ngalan sa imong cluster sa Ambari,
  • headers = {'X-Requested-By': 'ambari'}
  • ug sa sulod auth ania ang imong login ug password para sa Ambari: auth = ('login', 'password').

Ang function mismo wala’y labi pa sa usa ka magtiayon nga mga tawag pinaagi sa REST API sa Ambari. Gikan sa usa ka lohikal nga punto sa panglantaw, una kami makadawat og usa ka lista sa nagdagan nga mga serbisyo sa usa ka node, ug dayon mangutana sa usa ka gihatag nga cluster, sa usa ka gihatag nga node, sa pagbalhin sa mga serbisyo gikan sa listahan ngadto sa estado. INSTALLED. Mga gimbuhaton alang sa paglansad sa tanan nga mga serbisyo, alang sa pagbalhin sa mga node sa estado Maintenance ug uban pa susama tan-awon - kini pipila lang ka hangyo pinaagi sa API.

Klase nga Mc

Kini ang hitsura sa usa ka piraso sa code nga adunay usa ka klase 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

Sa entrada sa klase Mcs gipasa namo ang project id sulod sa cloud ug ang user id, ingon man ang iyang password. Sa function vm_turn_on gusto namong i-on ang usa sa mga makina. Ang lohika dinhi mas komplikado. Sa sinugdanan sa code, tulo pa ka mga function ang gitawag: 1) kinahanglan nga makakuha kita og token, 2) kinahanglan natong i-convert ang hostname ngadto sa ngalan sa makina sa MCS, 3) pagkuha sa id niini nga makina. Sunod, naghimo lang kami usa ka hangyo sa post ug ilunsad kini nga makina.

Mao kini ang hitsura sa function sa pagkuha og token:

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

Klase sa Autoscaler

Kini nga klase adunay mga gimbuhaton nga may kalabotan sa operating logic mismo.

Mao kini ang hitsura sa usa ka piraso sa code alang niini nga klase:

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

Gidawat namo ang mga klase alang sa pagsulod. Ambari и Mcs, usa ka lista sa mga node nga gitugotan sa pag-scale, ingon man mga parameter sa pagsumpo sa node: memorya ug cpu nga gigahin sa node sa YARN. Adunay usab 2 internal nga mga parameter q_ram, q_cpu, nga mga pila. Gigamit kini, gitipigan namon ang mga kantidad sa karon nga pagkarga sa cluster. Kung nakita namon nga sa miaging 5 ka minuto adunay kanunay nga pagtaas sa karga, nan kami nakahukom nga kinahanglan namon nga idugang ang +1 node sa cluster. Tinuod usab kini alang sa kahimtang sa underutilization sa cluster.

Ang code sa ibabaw usa ka pananglitan sa usa ka function nga nagtangtang sa usa ka makina gikan sa cluster ug gipahunong kini sa panganod. Una adunay decommissioning YARN Nodemanager, unya ang mode mo-on Maintenance, unya gipahunong namo ang tanang serbisyo sa makina ug gipalong ang virtual machine sa panganod.

2. Script observer.py

Sample code gikan didto:

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)

Niini, among gisusi kung ang mga kondisyon nahimo ba alang sa pagdugang sa kapasidad sa cluster ug kung adunay mga makina nga gireserba, kuhaa ang hostname sa usa niini, idugang kini sa cluster ug imantala ang usa ka mensahe bahin niini sa Slack sa among team. Human nga kini magsugod cooldown_period, kung dili kami magdugang o magtangtang bisan unsa gikan sa cluster, apan pagmonitor lang sa load. Kung kini nag-stabilize ug naa sa sulod sa koridor sa labing maayo nga mga kantidad sa pagkarga, nan magpadayon kami sa pag-monitor. Kung dili igo ang usa ka node, unya dugangan namon ang lain.

Alang sa mga kaso kung adunay usa ka leksyon sa unahan, nahibal-an na namon nga sigurado nga ang usa ka node dili igo, mao nga gisugdan dayon namon ang tanan nga libre nga mga node ug gipadayon kini nga aktibo hangtod sa katapusan sa leksyon. Kini mahitabo gamit ang usa ka lista sa mga timestamp sa kalihokan.

konklusyon

Ang Autoscaler usa ka maayo ug sayon ​​​​nga solusyon alang sa mga kaso kung makasinati ka nga dili parehas nga pagkarga sa cluster. Dungan nimo nga makab-ot ang gitinguha nga configuration sa cluster alang sa peak load ug sa samang higayon ayaw itago kini nga cluster atol sa underload, makadaginot og kwarta. Aw, dugang pa nga kining tanan awtomatikong mahitabo nga wala ang imong pag-apil. Ang autoscaler mismo wala’y labaw sa usa ka hugpong sa mga hangyo sa cluster manager API ug ang cloud provider API, nga gisulat sumala sa usa ka piho nga lohika. Ang kinahanglan nimong hinumdoman mao ang pagbahin sa mga node sa 3 nga mga tipo, sama sa among gisulat kaniadto. Ug magmalipayon ka.

Source: www.habr.com

Idugang sa usa ka comment