Clients can load data-sets and we need to select the node on which the
dataset will be loaded and refuse to load / avoid an OOM error if
there is no one machine which could fit the dataset.
This is a job scheduling problem ie I have finite resources how do we best utilize them. I'll get the OOM issue near the end.
We have one of the main factors ie RAM but solutions to scheduling problems are dependent on many factors ie...
Are the jobs small or large ie are there hundreds/thousands of these running on a node or two or three. Think Linux scheduler.
Do they need to complete in a particular time frame? Realtime Scheduler.
Given everything we know at the start of a job can we predict when a job will end within some time frame? If we can predict that on Node X we free up 100MB every 15 - 20 seconds we have a way to schedule a 200Mb job on that node ie I'm confident that in 40 seconds I'll have completed 200Mb of space on that node and the 40 seconds is an acceptable limit for the person or machine submitting the job.
Lets assume that we have a function as follows.
predicted_time predict(long bytes[, factors]);
The factors
are the other things we would need to take into consideration that I mentioned above and for every application there will be things you can add to suit your scenario ie how many factors is up to you.
The factors would be given weights when calculating predicted_time
.
predicted_time
is the number of milliseconds (can be any TimeUnit) that this node believes from now that it can service this Task, the node giving you the smallest number is the node the job should be scheduled on. You could then use this function as follows where we have a queue of tasks ie, in the following code this.nodes[i]
represents a JVM instance.
private void scheduleTask() {
while(WorkEvent()) {
while(!this.queue.isEmpty()) {
Task t = this.queue.poll();
for (int i = 0; i < this.maxNodes; i++) {
long predicted_time = this.nodes[i].predict(t);
if (predicted_time < 0) {
boolean b = this.queue.offer(t);
assert(b);
break;
}
if (predicted_time <= USER_EXPERIENCE_DELAY) {
this.nodes[i].addTask(t);
break;
}
alert_user(boolean b = this.queue.offer(t);
assert(b);
}
}
}
}
If predicted_time < 0
we have an error, we reschedule the job, in reality we'd like to know why but that's not difficult to add. If the predicted_time <= USER_EXPERIENCE_DELAY
the job can be scheduled.
How does this avoid an OOM
We can gather any statistics we want from our scheduler ie how many jobs of size X where scheduled correctly, the aim would be to reduce the errors and to make it more reliable over time ie reduce the amount of times we tell a customer that their job cannot be serviced or it failed. What we've done or at least are trying to attempt is to reduce the problem to something we can statistically improve upon towards an optimal solution.