Quid facere tua autoscaler pro botro

Salve! Nos homines ad operandum magnis data exercemus. Impossibile est imaginari programmatum scholasticum in magnis data notitia sine suo botro, in quo omnes participes simul cooperantur. Quam ob rem progressio noster semper eam habet Nos in eius configuratione, tuning et administratione versamur, et guys MapReduce jobs illic directe deducunt et scintilla utuntur.

In hac posta narrabimus tibi quomodo problema de inaequale botri oneratum solvimus scribendo nostro autoschali utendo nube. Mail.ru Cloud Solutions.

quaestio

Botrus noster in typico modo non est usus. Dispositio valde inaequabilis. Exempli gratia, sunt classes practicae, cum omnes XXX homines et magister vadunt ad botrum et committitur utendo. Vel iterum sunt dies ante fatalibus cum onus multum crescit. Reliquum temporis botrus operatur in modus underload.

Solutio #1 est botrum servare qui apicem onerum sustinebit, sed reliquum temporis erit otiosum.

Solutio #2 est serva botrum parvum, cui manually nodos ante classes et in cacumine sarcinas addis.

Solutio #3 est botrum servare et scribe autoscalarium qui monetam oneris botri monebit et, variis APIs utens, nodos ex botro adiciet et removebit.

In hac posta de solutione loquemur. Hic autoscaler a factoribus externis magis quam internis valde pendet, et provisores saepe id non praebent. Utimur in Mail.ru Solutiones Nubes infrastructurae nubem et autoscalem scripserunt utentes MCS API. Et quoniam docemus quomodo operandum cum notitia, decrevimus ostendere quomodo simile autoscaler ad proposita tua scribere possis, et cum tua nube utere.

DE PRAEREQUISITIS

Primum, habebis botrum Hadoop. Exempli gratia, distributione HDP utimur.

Ut nodos tuos cito adiiciantur et tollantur, necesse est ut certam distributionem munerum inter nodos habeas.

  1. Magister nodi. Bene, nihil opus est singulas res explicare: principalis nodi botri, in quo, exempli gratia, scintilla agitator emittitur, si modo interactive uteris.
  2. Date node. Hic est nodi, in quo repones notitias in HDFS et ubi calculi fiunt.
  3. Nodus computans. Nodus hic est ubi tu nihil in HDFS condis, sed ubi calculi fiunt.

Clarus locus. Occurret autoscaling ex nodis tertii generis. Si initium sumere ac addere nodis secundi generis, celeritas responsionis valde gravis erit - decommissionis et remittendi horas in botro tuo accipiet. Quod quidem ex autoscaling non exspectas. Id est, primae et secundae specierum nodos non attingimus. Minimum viable botrum repraesentabunt, qui per durationem programmatis existet.

Itaque noster autoscaler in Pythone 3 scribitur, Ambari API ad officia botri administranda, usus API ex Mail.ru Cloud Solutions (MCS) pro machinis incipiendi et morandi.

Solutio architecturae

  1. OMNIBUS autoscaler.py. Tria genera continet: 1) munera ad operandum cum Ambari, 2) munera ad operandum cum MCS, 3) munera directe ad logicam autoscaler pertinentia.
  2. Script observer.py. Per se consistit in diversis regulis: quando et quibus momentis functiones autoscales appellamus.
  3. Configurationis file config.py. Continet, exempli gratia, index nodis permissos pro autoscaling et alios parametros, qui afficiunt, exempli gratia, quousque exspectandum sit a momento, novus nodi additus est. Sunt etiam indicationes in initio classium, ita ut ante genus maximum permittitur figura botri emissa.

Nunc inspiciamus fragmenta codicis in duobus primis fasciculis.

1. Autoscaler.py moduli

Ambari classis

Hoc est fragmen codice continentur in genere similis 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

Superius, ut exemplum, exsecutionem muneris intueri potes stop_all_servicesqui sistit in optato nodo muneris omnes.

In faucibus in class Ambari transibis;

  • ambari_urlexempli gratia, sicut 'http://localhost:8080/api/v1/clusters/',
  • cluster_name nomen botri in Ambari.
  • headers = {'X-Requested-By': 'ambari'}
  • et intus auth Hic est username et password pro Ambari: auth = ('login', 'password').

Munus ipsum nihil aliud est quam duo vocat via CAETERA API Ambari. Secundum rationem logicam, primum album cursus officiorum in nodo accipimus, et deinde dato nodo datam botrum petimus ut operas e indice in rem publicam transferamus. INSTALLED. Munera pro omnibus officiis deducendis, nodis transferendis in statum Maintenance etc. vide similes — paucae petitiones per API sunt.

Classis Mcs

Hoc est fragmen codice continentur in genere similis 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

In faucibus in class Mcs Project id intra nubem et id utentis transimus, necnon tesseram eius. In munus vm_turn_on in unam machinis converti volumus. Dialectica hic paulo est multiplex. In initio codicis tria alia munera vocantur: 1) signum acquirere, 2) nomen hostname in nomen machinae in MCS convertere, 3) id machinae obtinere. Deinde simpliciter postulationem facimus et hanc machinam deducimus.

Hoc est quod munus obtinendi signum similis est;

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

Classis Autoscaler

Hoc genus munera continet ad ipsam logicam operantem pertinentia.

Hoc est quod fragmen codice huic classis similis:

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

Classes pro ingressu accipimus. Ambari и Mcs, index nodi qui ad scalas permittitur, necnon parametri conformationis nodi: memoria et cpu nodi in NARRATIO partita. Sunt etiam 2 parametri interni q_ram, q_cpu, que sunt queues. Illis utentes, valores botri currentis onus condimus. Si viderimus per ultimam 5 minutam onus constanter auctum fuisse, decernimus nos nodi -1 botro addere opus esse. Idem dicendum est de botri underutilizationis statu.

Codex superius est exemplum functionis quae machinam a botro removet et in nube sistit. Primum est decommissioning YARN NodemanagerErgo modus volvitur in Maintenancecessamus ergo omnia officia in machina et virtualem machinam in nube averte.

2. Script observer.py

Sample codicem inde:

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)

In ea perspicimus num condiciones factae sint ad augendam capacitatem botri et num aliquae machinae in subsidiis sint, unum ex eis nomen accipe, botrum adde et nuntium de illo in quadrigis nostris Slack evulgare. Post quem incipit cooldown_periodquando non addimus vel de botro aliquid auferimus, sed onus simpliciter monuimus. Si confirmatae sunt et intra in ANDRON bonarum bonorum onus est, tunc simpliciter vigilantia permanemus. Si una nodi satis fuit, aliam addimus.

Cum enim praemissam lectionem habeamus, iam pro certo scimus unam nodi non esse satis, ita statim omnes nodos liberas incipimus et eas activas usque ad finem lectionis servamus. Hoc fit utens indice actionis indicationibus.

conclusio,

Autoscaler bona et commoda solutio casuum est cum inaequale oneratum botrum experieris. Simul optatum botri configurationem ad apicem onerum assequeris et simul hoc botrum in onere sub onere non servas, pecuniam salvificam. Bene, plus haec omnia fiunt statim sine participatione tua. Ipsum autoscaler nihil aliud est quam postulationes ad botrum procurator API et nubes provisor API, scripta secundum quamdam logicam. Quod certe meminisse debes est divisio nodis in 3 species, sicut antea scripsimus. Et beatus eris.

Source: www.habr.com

Add a comment