Um guia para o Apache Mesos

Um guia para o Apache Mesos

1. Visão geral

Geralmente, implantamos vários aplicativos no mesmo cluster de máquinas. Por exemplo, é comum hoje em dia ter um mecanismo de processamento distribuído comoApache Spark ouApache Flink com bancos de dados distribuídos comoApache Cassandra no mesmo cluster.

Apache Mesos é uma plataforma que permite o compartilhamento eficaz de recursos entre esses aplicativos.

Neste artigo, vamos primeiro discutir alguns problemas de alocação de recursos em aplicativos implantados no mesmo cluster. Posteriormente, veremos como o Apache Mesos fornece melhor utilização de recursos entre aplicativos.

2. Compartilhando o Cluster

Muitos aplicativos precisam compartilhar um cluster. De um modo geral, existem duas abordagens comuns:

  • Particione o cluster estaticamente e execute um aplicativo em cada partição

  • Alocar um conjunto de máquinas para um aplicativo

Embora essas abordagens permitam que os aplicativos sejam executados independentemente uns dos outros, não alcançam alta utilização de recursos.

Por exemplo, considere um aplicativo queruns only for a short period followed by a period of inactivity. Agora, uma vez que alocamos máquinas estáticas ou partições para este aplicativo, temosunutilized resources during the inactive period.

Podemos otimizar a utilização de recursos realocando recursos gratuitos durante o período inativo para outros aplicativos.

O Apache Mesos ajuda na alocação dinâmica de recursos entre aplicativos.

3. Apache Mesos

Com as duas abordagens de compartilhamento de cluster que discutimos acima, os aplicativos conhecem apenas os recursos de uma partição ou máquina específica que estão executando. No entanto, o Apache Mesos fornece uma visão abstrata de todos os recursos no cluster para aplicativos.

Como veremos em breve, o Mesos atua como uma interface entre máquinas e aplicativos. Ele fornece aos aplicativosavailable resources on all machines in the cluster. Itfrequently updates this information to include resources that are freed up by applications que alcançaram o status de conclusão. Isso permite que os aplicativos tomem a melhor decisão sobre qual tarefa executar em qual máquina.

Para entender como o Mesos funciona, vamos dar uma olhada em seuarchitecture:

image

Esta imagem faz parte da documentação oficial do Mesos. Aqui,HadoopeMPI são dois aplicativos que compartilham o cluster.

Falaremos sobre cada componente mostrado aqui nas próximas seções.

3.1. Mesos Master

Mestre é o componente principal nesta configuração e armazena o estado atual dos recursos no cluster. Além disso, ele atua como um orchestrator between the agentse os aplicativos, passando informações sobre coisas como recursos e tarefas.

Como qualquer falha no mestre resulta na perda de estado sobre recursos e tarefas, nós a implantamos na configuração de alta disponibilidade. Como pode ser visto no diagrama acima, o Mesos implementa daemons mestre em espera junto com um líder. Esses daemons contam com o Zookeeper para recuperar o estado em caso de falha.

3.2. Mesos Agents

Um cluster do Mesos deve executar um agente em todas as máquinas. Esses agentesreport their resources to the master periodicallye por sua vez,receive tasks that an application has scheduled to run. Esse ciclo se repete depois que a tarefa agendada é concluída ou perdida.

Veremos como os aplicativos agendam e executam tarefas nesses agentes nas seções a seguir.

3.3. Mesos Frameworks

O Mesos permite que os aplicativos implementem um componente abstrato que interage com o Master parareceive the available resources in the clusteremake scheduling decisions com base neles. Esses componentes são conhecidos como estruturas.

Uma estrutura Mesos é composta por dois subcomponentes:

  • Scheduler - permite que os aplicativos agendem tarefas com base nos recursos disponíveis em todos os agentes

  • Executor - é executado em todos os agentes e contém todas as informações necessárias para executar qualquer tarefa agendada naquele agente

Todo esse processo é representado com este fluxo:

 

image

Primeiro, os agentes relatam seus recursos ao mestre. Nesse instante, o mestre oferece esses recursos a todos os agendadores registrados. Esse processo é conhecido como oferta de recursos e vamos discuti-lo em detalhes na próxima seção.

O agendador escolhe o melhor agente e executa várias tarefas nele através do Master. Assim que o executor concluir a tarefa atribuída, os agentes republicam seus recursos no mestre. O mestre repete esse processo de compartilhamento de recursos para todas as estruturas do cluster.

O Mesos permite aplicativos paraimplement their custom scheduler and executor em várias linguagens de programação. Uma implementação Java do planejador deveimplementthe Scheduler interface:

public class HelloWorldScheduler implements Scheduler {

    @Override
    public void registered(SchedulerDriver schedulerDriver, Protos.FrameworkID frameworkID,
      Protos.MasterInfo masterInfo) {
    }

    @Override
    public void reregistered(SchedulerDriver schedulerDriver, Protos.MasterInfo masterInfo) {
    }

    @Override
    public void resourceOffers(SchedulerDriver schedulerDriver, List list) {
    }

    @Override
    public void offerRescinded(SchedulerDriver schedulerDriver, OfferID offerID) {
    }

    @Override
    public void statusUpdate(SchedulerDriver schedulerDriver, Protos.TaskStatus taskStatus) {
    }

    @Override
    public void frameworkMessage(SchedulerDriver schedulerDriver, Protos.ExecutorID executorID,
      Protos.SlaveID slaveID, byte[] bytes) {
    }

    @Override
    public void disconnected(SchedulerDriver schedulerDriver) {
    }

    @Override
    public void slaveLost(SchedulerDriver schedulerDriver, Protos.SlaveID slaveID) {
    }

    @Override
    public void executorLost(SchedulerDriver schedulerDriver, Protos.ExecutorID executorID,
      Protos.SlaveID slaveID, int i) {
    }

    @Override
    public void error(SchedulerDriver schedulerDriver, String s) {
    }
}

Como pode ser visto, consiste principalmente emvarious callback methods for communication with the master em particular.

Da mesma forma, a implementação de um executor deve implementar a sinterfaceExecutor :

public class HelloWorldExecutor implements Executor {
    @Override
    public void registered(ExecutorDriver driver, Protos.ExecutorInfo executorInfo,
      Protos.FrameworkInfo frameworkInfo, Protos.SlaveInfo slaveInfo) {
    }

    @Override
    public void reregistered(ExecutorDriver driver, Protos.SlaveInfo slaveInfo) {
    }

    @Override
    public void disconnected(ExecutorDriver driver) {
    }

    @Override
    public void launchTask(ExecutorDriver driver, Protos.TaskInfo task) {
    }

    @Override
    public void killTask(ExecutorDriver driver, Protos.TaskID taskId) {
    }

    @Override
    public void frameworkMessage(ExecutorDriver driver, byte[] data) {
    }

    @Override
    public void shutdown(ExecutorDriver driver) {
    }
}

Veremos uma versão operacional do planejador e do executor em uma seção posterior.

4. Gestão de recursos

4.1. Ofertas de Recursos

Como discutimos anteriormente, os agentes publicam suas informações de recursos no mestre. Por sua vez, o mestre oferece esses recursos para as estruturas em execução no cluster. Este processo é conhecido comoresource offer.

Uma oferta de recursos consiste em duas partes - recursos e atributos.

Os recursos são usados ​​parapublish hardware information of the agent machine, como memória, CPU e disco.

Existem cinco recursos predefinidos para cada agente:

  • cpu

  • gpus

  • mem

  • disk

  • portos

Os valores para esses recursos podem ser definidos em um dos três tipos:

  • Scalar - usado para representar informações numéricas usando números de ponto flutuante para permitir valores fracionários, como 1,5 G de memória

  • Range - usado para representar um intervalo de valores escalares - por exemplo, um intervalo de porta

  • Set - usado para representar vários valores de texto

Por padrão, o agente do Mesos tenta detectar esses recursos da máquina.

No entanto, em algumas situações, podemos configurar recursos personalizados em um agente. Os valores para esses recursos personalizados devem estar novamente em qualquer um dos tipos discutidos acima.

Por exemplo, podemos iniciar nosso agente com estes recursos:

--resources='cpus:24;gpus:2;mem:24576;disk:409600;ports:[21000-24000,30000-34000];bugs(debug_role):{a,b,c}'

Como pode ser visto, configuramos o agente com alguns dos recursos predefinidos e um recurso personalizado denominadobugs que é do tiposet .

Além de recursos, os agentes podem publicar atributos de valor-chave no mestre. Esses atributos atuam como metadados adicionais para o agente e ajudam as estruturas nas decisões de planejamento.

Um exemplo útil pode seradd agents into different racks or zoneseschedule various tasks on the same rack or zone para obter a localidade dos dados:

--attributes='rack:abc;zone:west;os:centos5;level:10;keys:[1000-1500]'

Semelhante aos recursos, os valores para atributos podem ser um escalar, um intervalo ou um tipo de texto.

4.2. Funções de Recursos

Muitos sistemas operacionais modernos oferecem suporte a vários usuários. Da mesma forma, o Mesos também suporta vários usuários no mesmo cluster. Esses usuários são conhecidos comoroles. Podemos considerar cada função como consumidor de recursos em um cluster.

Devido a isso, os agentes do Mesos podem particionar os recursos em diferentes funções com base em diferentes estratégias de alocação. Além disso, as estruturas podem assinar essas funções no cluster e ter controle refinado sobre os recursos em diferentes funções.

Por exemplo, considere acluster hosting applications which are serving different users em uma organização. Então, pordividing the resources into roles, every application can work in isolation um do outro.

Além disso, as estruturas podem usar essas funções para alcançar a localidade dos dados.

Por exemplo, suponha que temos dois aplicativos no cluster chamadosproducer andconsumer. Aqui,producer transfere os dados para um volume persistente queconsumer can lê depois. Podemos otimizar a aplicaçãoconsumer compartilhando o volume comproducer.

Como o Mesos permite que vários aplicativos se inscrevam na mesma função, podemos associar o volume persistente a uma função de recurso. Além disso, as estruturas paraproducer andconsumer will assinam a mesma função de recurso. Portanto, o sapplicationconsumer agora pode iniciar a tarefa de leitura de dadoson the same volume como o sapplicationproducer .

4.3. Reserva de Recursos

Agora, pode surgir a questão de como o Mesos aloca recursos de cluster em diferentes funções. Mesos aloca os recursos através de reservas.

Existem dois tipos de reservas:

  • Reserva Estática

  • Reserva dinâmica

A reserva estática é semelhante à alocação de recursos na inicialização do agente, discutida nas seções anteriores:

 --resources="cpus:4;mem:2048;cpus(example):8;mem(example):4096"

A única diferença aqui é que agora o agente Mesosreserves eight CPUs and 4096m of memory for the role named example.

A reserva dinâmica nos permite reorganizar os recursos nas funções, diferentemente da reserva estática. O Mesos permite que frameworks e operadores de cluster alterem dinamicamente a alocação de recursos por meio de mensagens de framework como uma resposta à oferta de recursos ou viaHTTP endpoints.

O Mesos aloca todos os recursos sem nenhuma função para uma função padrão chamada (*). O Master oferece esses recursos a todas as estruturas, independentemente de terem se inscrito ou não.

4.4. Pesos e cotas de recursos

Geralmente, o mestre do Mesos oferece recursos usando uma estratégia de justiça. Ele usa a equidade de recursos dominante ponderada (wDRF) para identificar as funções que carecem de recursos. O mestre então oferece mais recursos para as estruturas que se inscreveram nessas funções.

Embora o compartilhamento justo de recursos entre aplicativos seja uma característica importante do Mesos, nem sempre é necessário. Suponha que um cluster hospede aplicativos com baixo consumo de recursos, além daqueles com alta demanda de recursos. Nessas implantações, gostaríamos de alocar recursos com base na natureza do aplicativo.

Mesos permite estruturas parademand more resources by subscribing to roles and adding a higher value of weight for that role. Portanto,if there are two roles, one of weight 1 and another of weight 2, Mesos will allocate twice the fair share of resources to the second role.

Semelhante aos recursos, podemos configurar pesos viaHTTP endpoints.

Além de garantir uma parte justa dos recursos para uma função com pesos, Mesos também garante quethe minimum resources for a role are allocated.

Mesos nos permiteadd quotas to the resource roles. Uma cota especificathe minimum amount of resources that a role is guaranteed to receive.

5. Quadro de Implementação

Como discutimos em uma seção anterior, o Mesos permite que os aplicativos forneçam implementações de estrutura em um idioma de sua escolha. Em Java, um framework é implementado usando a classe principal - que atua como um ponto de entrada para o processo do framework - e a implementação deScheduler andExecutor discutido anteriormente.

5.1. Classe Principal do Framework

Antes de implementar um planejador e um executor, vamos primeiro implementar o ponto de entrada para nossa estrutura que:

  • Registra-se no mestre

  • Fornece informações de tempo de execução do executor aos agentes

  • Inicia o agendador

Vamos primeiro adicionar umMaven dependency para Mesos:


    org.apache.mesos
    mesos
    0.28.3

Em seguida, vamos implementar oHelloWorldMain  para nossa estrutura. Uma das primeiras coisas que faremos é iniciar o processo do executor no agente Mesos:

public static void main(String[] args) {

    String path = System.getProperty("user.dir")
      + "/target/libraries2-1.0.0-SNAPSHOT.jar";

    CommandInfo.URI uri = CommandInfo.URI.newBuilder().setValue(path).setExtract(false).build();

    String helloWorldCommand = "java -cp libraries2-1.0.0-SNAPSHOT.jar com.example.mesos.executors.HelloWorldExecutor";
    CommandInfo commandInfoHelloWorld = CommandInfo.newBuilder()
      .setValue(helloWorldCommand)
      .addUris(uri)
      .build();

    ExecutorInfo executorHelloWorld = ExecutorInfo.newBuilder()
      .setExecutorId(Protos.ExecutorID.newBuilder()
      .setValue("HelloWorldExecutor"))
      .setCommand(commandInfoHelloWorld)
      .setName("Hello World (Java)")
      .setSource("java")
      .build();
}

Aqui, primeiro configuramos o local binário do executor. O agente Mesos baixaria esse binário no registro da estrutura. Em seguida, o agente executaria o comando fornecido para iniciar o processo do executor.

A seguir, inicializaremos nossa estrutura e iniciaremos o programador:

FrameworkInfo.Builder frameworkBuilder = FrameworkInfo.newBuilder()
  .setFailoverTimeout(120000)
  .setUser("")
  .setName("Hello World Framework (Java)");

frameworkBuilder.setPrincipal("test-framework-java");

MesosSchedulerDriver driver = new MesosSchedulerDriver(new HelloWorldScheduler(),
  frameworkBuilder.build(), args[0]);

Finalmente,we’ll start the MesosSchedulerDriver that registers itself with the Master. For successful registration, we must pass the IP of the Master as a program argument args[0] to this main class:

int status = driver.run() == Protos.Status.DRIVER_STOPPED ? 0 : 1;

driver.stop();

System.exit(status);

Na classe mostrada acima,CommandInfo, ExecutorInfo,eFrameworkInfo são todas representações Java deprotobuf messages entre mestre e estruturas.

5.2. Implementando o Agendador

Desde Mesos 1.0,we can invoke the HTTP endpoint from any Java application to send and receive messages to the Mesos master. Algumas dessas mensagens incluem, por exemplo, registro de estrutura, ofertas de recursos e rejeições de ofertas.

ParaMesos 0.28 or earlier, we need to implement the Scheduler interface:

Na maior parte, vamos nos concentrar apenas no métodoresourceOffers deScheduler.. Vamos ver como um planejador recebe recursos e inicializa tarefas com base neles.

Primeiro, veremos como o agendador aloca recursos para uma tarefa:

@Override
public void resourceOffers(SchedulerDriver schedulerDriver, List list) {

    for (Offer offer : list) {
        List tasks = new ArrayList();
        Protos.TaskID taskId = Protos.TaskID.newBuilder()
          .setValue(Integer.toString(launchedTasks++)).build();

        System.out.println("Launching printHelloWorld " + taskId.getValue() + " Hello World Java");

        Protos.Resource.Builder cpus = Protos.Resource.newBuilder()
          .setName("cpus")
          .setType(Protos.Value.Type.SCALAR)
          .setScalar(Protos.Value.Scalar.newBuilder()
            .setValue(1));

        Protos.Resource.Builder mem = Protos.Resource.newBuilder()
          .setName("mem")
          .setType(Protos.Value.Type.SCALAR)
          .setScalar(Protos.Value.Scalar.newBuilder()
            .setValue(128));

Aqui, alocamos 1 CPU e 128M de memória para nossa tarefa. A seguir, usaremos oSchedulerDriver para iniciar a tarefa em um agente:

        TaskInfo printHelloWorld = TaskInfo.newBuilder()
          .setName("printHelloWorld " + taskId.getValue())
          .setTaskId(taskId)
          .setSlaveId(offer.getSlaveId())
          .addResources(cpus)
          .addResources(mem)
          .setExecutor(ExecutorInfo.newBuilder(helloWorldExecutor))
          .build();

        List offerIDS = new ArrayList<>();
        offerIDS.add(offer.getId());

        tasks.add(printHelloWorld);

        schedulerDriver.launchTasks(offerIDS, tasks);
    }
}

Como alternativa,Scheduler frequentemente encontra a necessidade de rejeitar ofertas de recursos. Por exemplo, se oScheduler cannão iniciar uma tarefa em um agente devido à falta de recursos, ele deve recusar imediatamente essa oferta:

schedulerDriver.declineOffer(offer.getId());

5.3. ImplementandoExecutor

Como discutimos anteriormente, o componente executor da estrutura é responsável pela execução de tarefas de aplicativo no agente Mesos.

Usamos os pontos de extremidade HTTP para implementarScheduler no Mesos 1.0. Da mesma forma, podemos usarHTTP endpoint para o executor.

Em uma seção anterior, discutimos como uma estrutura configura um agente para iniciar o processo do executor:

java -cp libraries2-1.0.0-SNAPSHOT.jar com.example.mesos.executors.HelloWorldExecutor

Notavelmente,this command considers HelloWorldExecutor as the main class. Implementaremos este métodomain parainitialize the MesosExecutorDriver que se conecta a agentes Mesos para receber tarefas e compartilhar outras informações como o status da tarefa:

public class HelloWorldExecutor implements Executor {
    public static void main(String[] args) {
        MesosExecutorDriver driver = new MesosExecutorDriver(new HelloWorldExecutor());
        System.exit(driver.run() == Protos.Status.DRIVER_STOPPED ? 0 : 1);
    }
}

A última coisa a fazer agora é aceitar tarefas da estrutura e iniciá-las no agente. As informações para iniciar qualquer tarefa são autocontidas noHelloWorldExecutor:

public void launchTask(ExecutorDriver driver, TaskInfo task) {

    Protos.TaskStatus status = Protos.TaskStatus.newBuilder()
      .setTaskId(task.getTaskId())
      .setState(Protos.TaskState.TASK_RUNNING)
      .build();
    driver.sendStatusUpdate(status);

    System.out.println("Execute Task!!!");

    status = Protos.TaskStatus.newBuilder()
      .setTaskId(task.getTaskId())
      .setState(Protos.TaskState.TASK_FINISHED)
      .build();
    driver.sendStatusUpdate(status);
}

Obviamente, essa é apenas uma implementação simples, mas explica como um executor compartilha o status da tarefa com o mestre em cada estágio e depois executa a tarefa antes de enviar um status de conclusão.

Em alguns casos, os executores também podem enviar dados de volta ao agendador:

String myStatus = "Hello Framework";
driver.sendFrameworkMessage(myStatus.getBytes());

6. Conclusão

Neste artigo, discutimos brevemente o compartilhamento de recursos entre aplicativos em execução no mesmo cluster. Também discutimos como o Apache Mesos ajuda os aplicativos a obter a máxima utilização com uma visão abstrata dos recursos do cluster, como CPU e memória.

Posteriormente, discutimos odynamic allocation of resources between applications com base emvarious fairness policies and roles. Mesos permite que aplicativos façamscheduling decisions based on resource offers a partir de agentes Mesos no cluster.

Por fim, vimos uma implementação da estrutura do Mesos em Java.

Como de costume, todos os exemplos estão disponíveisover on GitHub.