Cómo crear tu propio framework para Apache Mesos

Última actualización: 04/10/2020

En este post vamos a explorar cómo desarrollar tu propio framework para la tecnología Apache Mesos para Big Data.

aprende a crear frameworks de apache mesos

Apache Mesos es conocido por gestionar los recursos de un clúster (CPU, RAM, GPU, etc) monitorizándolos y realizando ofertas para aplicaciones (llamadas frameworks) que realizan procesamiento con estos recursos. Algunos ejemplos de los frameworks más extendidos se pueden encontrar aquí.

La razón principal de desarrollar un framework propio es que nos da la capacidad de controlar qué se ejecuta, dónde y cómo de forma precisa. De esta forma Mesos se encarga de resolver los problemas asociados a la ejecución distribuida para que nos podamos centrar en implementar la lógica de negocio y el caso de uso, por ejemplo priorizar tareas o escalar el servicio ante unos determinados eventos.

Por lo tanto, generalmente cuando necesitemos usar algún indicador para priorizar cargas de trabajo deberíamos considerar escribir un framework específico.

La siguiente imagen muestra la arquitectura básica de un clúster de Mesos. Podemos observar que existe un nodo Master elegido que se encarga de monitorizar los recursos de los nodos “Slave” del cluster y realiza ofertas a los frameworks.

Arquitectura Big Data Apache Mesos
Arquitectura Apache Mesos

Estos frameworks pueden aceptar estas ofertas y usarlas para ejecutar cargas de trabajo en los ejecutores de los nodos “Slave”.

Ahora vamos a escribir un framework mínimo de ejemplo para comprender cómo se realiza esta comunicación, para ello usaremos la API disponible en Java.

Podéis encontrar este código en Github.

Generalmente, la implementación de un framework para Mesos se divide en tres componentes: Driver, Scheduler y Executor; que se pueden desarrollar de forma independiente. En nuestro caso vamos a implementarlos en el mismo paquete para simplificar el ejemplo.

Paso 1 – Registrar nuestro framework en Mesos (Driver):

Lo primero que debe realizar un framework es registrarse con el nodo master elegido para poder empezar a recibir ofertas de recursos. Estas ofertas deberán tratarse posteriormente en nuestro Scheduler usando la clase de Java MesosSchedulerDriver:

private static void runFramework(String mesosMaster) {
    Scheduler scheduler = new ExampleScheduler(getExecutorInfo());
    MesosSchedulerDriver driver = new MesosSchedulerDriver(scheduler,
                getFrameworkInfo(), mesosMaster);
    int status = driver.run() == Protos.Status.DRIVER_STOPPED ? 0 : 1;
 
    driver.stop();
    System.exit(status);
}

Paso 2 – Ejecutar tareas (Scheduler):

El segundo paso consiste en implementar el Scheduler. Para ejecutar tareas debemos usar el método resourceOffers (de la clase org.apache.mesos.Scheduler). En este ejemplo vamos a aceptar todas las ofertas que nos lleguen y para cada una de ellas programar una nueva tarea de 1 CPU y 128 MB de RAM.

public void resourceOffers(SchedulerDriver schedulerDriver, List offers) {
 
    for (Protos.Offer offer : offers) {
        Protos.TaskID taskId = buildNewTaskID();
        Protos.TaskInfo task = Protos.TaskInfo.newBuilder()
            .setName("task " + taskId).setTaskId(taskId)
            .setSlaveId(offer.getSlaveId())
            .addResources(buildResource("cpus", 1))
            .addResources(buildResource("mem", 128))
            .setData(ByteString.copyFromUtf8("" + taskIdCounter))
            .setExecutor(Protos.ExecutorInfo.newBuilder(executorInfo))
            .build();
        launchTask(schedulerDriver, offer, task);
    }
}

Para ejecutar una tarea debemos indicar qué oferta aceptamos y cómo configurar la nueva tarea. En un framework real deberíamos analizar los recursos ofrecidos y en función de estos ajustar las configuraciones de la tarea. También es posible enviar mensajes entre el framework y el ejecutor de la tarea.

Otro método importante del Scheduler es “statusUpdate“. Este método se invoca cuando el estado de una tarea cambia, por ejemplo cuando se pierde un agente de Mesos o una tarea termina.

Para este ejemplo vamos a mostrar un mensaje cuando se invoque cada uno de los métodos implementados.

Paso 3 – Ejecutor (Executor):

Por último debemos implementar la clase Executor. Este componente debe estar desacoplado del Scheduler. La interfaz que debe implementar el Ejecutor es org.apache.mesos.Executor y el método más importante para implementar es “launchTask”.

public void launchTask(ExecutorDriver executorDriver, Protos.TaskInfo taskInfo) {
 
    Integer id = Integer.parseInt(taskInfo.getData().toStringUtf8());
    String reply = id.toString();
    executorDriver.sendFrameworkMessage(reply.getBytes());
    Protos.TaskStatus status = Protos.TaskStatus.newBuilder()
            .setTaskId(taskInfo.getTaskId())
            .setState(Protos.TaskState.TASK_FINISHED).build();
    executorDriver.sendStatusUpdate(status);
}

Este método se invoca cuando se ha ejecutado una tarea en el ejecutor. En nuestro ejemplo estamos enviando de vuelta al framework el mensaje recibido del Scheduler e indicando a Mesos que la tarea se ha ejecutado correctamente. Este es el momento de gestionar la ejecución de tareas, de procesos y de enviar los mensajes de estado correspondientes.

Como hemos visto, escribir un framework nos permite centrarnos en implementar la lógica de gestión que necesitamos.

En artículos posteriores se ampliará la información paso a paso.

Este ejemplo está basado en el siguiente código que podemos encontrar en Github.


A continuación el vídeo-resumen. ¡No te lo pierdas!


¡Echa un ojo a mi lista de reproducción de Big Data en Youtube!

Si te ayuda el contenido del blog, por favor considera unirte a la lista de correo para reconocer el trabajo!

Deja una respuesta