What does the sample do?
This sample illustrates the implementation of a custom load-balancer
that uses information about the nodes and the submitted jobs, to dispatch JPPF tasks to the nodes.
Description of the problem to solve
We are in a situation where we need to submit two types of jobs for execution in the JPPF grid:
- "heavy jobs", made of a small number of long-lived tasks with a large memory footprint
- "light jobs", made of a large number of short-lived tasks with a small memory footprint
We want the JPPF server to be able to dispatch the tasks to the apppropriate node(s), based on what it knows of each node's capabilities and on the jobs characteristics.
Description of the solution
To resolve this problem, we will use a combination of a custom load balancer that is aware of the node's capabilities, execution policies for the jobs, and job metadata the load-balancer will be able to use.
a) Information provided by each job (job metadata):
- "task.memory": the maximum size in bytes neded by each task in the job
- "task.time": the maximum duration of each task in the job
- "allowed.time": the maximum allowed time for execution of a single set of tasks on a node
- "id": the job id (for debugging and logging purposes only)
- for full details, please take a look at the fully commented job runner source code
b) Information provided by each node:
- "maxMemory": the maximum heap size available to the node
- "processing.threads": the number of processing threads available to the node
c) Our load-balancer will compute the maximum number of tasks in the job that can be sent to a node, based on:
- the estimated total memory footprint of the tasks, which must fit in the node's available memory.
- the estimated total execution time, that must be less than the allowed time
- for full details, please take a look at the fully commented load-balancer source code
d) Furthermore, additional node filtering will be applied before the load-balancing comes into play, by the means of an execution policy for each job:
- heavy jobs can only be executed on nodes such that the amount of available memory per processing thread is at least the memory footprint of each task;
this will avoid under-utilization of nodes with many processing threads, while avoiding out of memory issues
- light jobs will only be executed on nodes that have at east 2 processing threads, to minimize the network transport overhead, which can be significant for short-lived tasks
Here is a set of links to the source of each Java class in this sample:
How do I run it?
Before running this sample, you need to install a JPPF server and at least two nodes.
For information on how to set up a node and server, please refer to the JPPF documentation
Once you have installed a server and node, perform the following steps:
- To configure the two nodes, there are 2 predefined node configurations we will use:
- copy CustomLoadBalancer/config/node1/jppf-node.properties to the config folder of your first node installation (it will replace the existing file).
This will setup the first node with 64 MB of heap and 1 processing thread; this node will be used for "heavy" jobs
- copy CustomLoadBalancer/config/node2/jppf-node.properties to the config folder of your second node installation (it will replace the existing file).
This will setup the second node with 64 MB of heap and 4 processing thread; this node will be used for "light" jobs
- open a command prompt in JPPF-x.y-samples-pack/CustomLoadBalancer
- build the sample: type "ant jar"; this will create a file named CustomLoadBalancer.jar
- copy CustomLoadBalancer.jar in the "lib" folder of the JPPF driver installation, to add it to the driver's classpath. This will effectively install the new load-balancer.
- in the server's installation config/jppf-driver.properties file, replace the property "jppf.load.balancing.algorithm = xxxxx" with "jppf.load.balancing.algorithm = customLoadBalancer",
to let the server know it must use the new load-balancer
- start the JPPF server and each of the 2 nodes
- the demo application should already be configured with a connection pool size of 2; to confirm it you can open the file jppf-client.properties in CustomerLoadbalancer/config, you should see a line "jppf.pool.size = 2"
- start the demo, by opening a console in JPPF-x.y-samples-pack/CustomLoadBalancer, and typing: "ant run"
- in the first node's console output you should see messages of this type:
[java] Starting execution of task Heavy Job - task 1 (as many as there are tasks in the "heavy" job)
- in the second node's console output you should see messages of this type:
[java] Starting execution of task Light Job - task 2 (as many as there are tasks in the "light" job)
- the demo console output should show something like this:
[java] ********** Results for job : Heavy Job **********
[java] Result for task Heavy Job - task 1 : the execution was performed successfully
[java] Result for task Heavy Job - task 2 : the execution was performed successfully
[java] Result for task Heavy Job - task 3 : the execution was performed successfully
[java] Result for task Heavy Job - task 4 : the execution was performed successfully
[java] ********** Results for job : Light Job **********
[java] Result for task Light Job - task 1 : the execution was performed successfully
[java] Result for task Light Job - task 2 : the execution was performed successfully
[java] Result for task Light Job - task 3 : the execution was performed successfully
[java] Result for task Light Job - task 4 : the execution was performed successfully
What features of JPPF are demonstrated?
I have additional questions and comments, where can I go?
If you need more insight into the code of this demo, you can consult the Java source files located in the CustomLoadBalancer/src folder.
In addition, There are 2 privileged places you can go to: