Custom mesos executor in Scala
In previous post, we discussed about how to write a simple mesos scheduler in Scala. In this post, we are going to see how to extend the scheduler to run general scala code.
This post assumes that you already know different components of writing a scheduler in Mesos. If not refer to this post.
tl;dr Access the complete example code here.
##Executor in Mesos In last example, we used built in mesos executor CommandExecutor to run the commands. Command executor is capable of running any operating system binaries. But if we want to run java/scala code,we have to write our own executor to setup the environment and run the code.
Writing custom executor is not that straight forward. There are multiple pieces to write to get a full fledged executor. The following steps shows how to build these pieces.
Step 1 : Task abstraction
To run any function, we need to represent that function as a mesos task. The following trait represent the task abstraction.
Our task has a single run method. It does not take anything. Type T signifies the return type of the function. Note that task extends the serialization which allows us to send this task over wire to execute on mesos cluster.
FunctionTask is one of the implementation which wraps a given function inside task.
Now we have a task abstraction which we can instruct our scheduler to run.
Step 2 : TaskExecutor
TaskExecutor is our custom executor which runs above task abstraction. It’s just a normal scala program which has a main method. It creates an instance of mesos.Executor and listens on launchTask callback.
In the code, we deserialize the task from the TaskInfo object. We run each task on different thread so that we can run multiple tasks at same time.
Once the execution is done, we wrap the result and set the task state to finished.
You can access complete code listing here.
Step 3 : Plug Custom Executor in Scheduler
Once we have the custom executor, next step is to plug it in our mesos scheduler. Mesos doesn’t understand any specific language, it just understands how to run shell scripts. So we run our task executor from a shell script and specify the shell script path in executor info.
Once we have executor info, we set for a given using setExecutor.
You can access complete code listing here.
Step 4 : run-executor script file
This script file, used by the executor info to instantiate our custom executor.
update project-path to the directory which has the build jar from code.
Step 5 : Creating tasks
We create 2 simple tasks to just to print hi and index. Note how we can even access closure inside our tasks.
Step 6 : Running
Clone complete code from github.
Run CustomTasks main method with mesos master url and path to the run-executor.sh shell script.
Step 7 : Output
The output should be available in mesos logs as specified here.