|
|||||||||||||||
|
|||||||||||||||
|
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Overview
We chose to demonstrate xTier/GRID using the prime finder example because it solves a well known and easily understood mathematical problem: finding the number of prime numbers in a given range. It is a good problem to demonstrate xTier/GRID because its "problem domain" is relatively simple (and generic) and it is an "embarrassingly parallel" problem and thus easily applicable to grid computing. Implementing a grid-enabled application with xTier/GRID is a straight forward task accomplished with three steps as the Prime Finder will demonstrate. First, we will write a simple class that implements the logic of finding the number of primes in a given numeric range. Then we will use this class to write a grid task. Last, we will run this grid task on the grid. Three easy steps, that's all there is to it! The entire source code one needs to write to run this task is in the following sections. This code will execute on 1 computer, 20 computers, or on a high-performance 100+ node Beowulf cluster with no changes. With xTier/GRID there’s absolutely no difference what-so-ever in the code or configuration as the application scales. Read on...
Prime Finder
PrimeFinder.java
The static method findPrimesCount(long min, long max) on line 9 is all we need. We pass the range extremities and it returns the number of primes within this range. Note that this algorithm is far from being efficient (especially for large numbers) and there are many better performing prime finding routines, but for the sake of this example, this approach is simple and sufficient enough. What is important to note is that this class has nothing to do with a grid computing per-se. It is what usually would be called the domain logic that we will grid-enable in the next chapter. So far, so good...
Prime Finder Grid Task
The essence of running something faster on the grid is practically the same old parallel computing axiom: take the task, split it into multiple sub-tasks, and execute these sub-tasks in parallel aggregating results back for overall faster execution. The following picture illustrates what happens in our trivial example (3 grid nodes + 1 driver node):
xTier/GRID has direct and simple support for this type of work. The two main concepts that one needs to understand in xTier/GRID are: grid task and grid task unit. Grid task is a holder for all grid-specific components that relate to the given grid task such as grid topology resolver, task unit router, failure resolver and task unit factory. For our simple example, however, we will need to create only a task unit factory that will be responsible for creating task units. Grid task unit is a simple unit of work (a sub-task) belonging to a grid task that "knows" how to execute itself (if needed), split itself into further sub-task units (if needed) and aggregate results from sub-task units (if needed). A grid task can be logically represented as a tree of task units where leaves are executed locally on their respective nodes, and non-leaf nodes get split into further sub-task units (shown below as the tree node’s children). Note that this representation is only logical and not physical: for example, the fact that task unit is split does not necessarily mean that sub-task units will be executed on different nodes (although it is usually the case), or in some cases task units can split differently or not split at all on each execution to accommodate for changing grid topology or other conditions. Every task and task unit has an ID. Both of these IDs define different types of tasks or task units and not the different instances. In the diagram below, for example, the task unit with UID2 gets split into two sub-task units of the same type and UID4:
A grid task is simply configured in the 'grid' service XML configuration via IoC-based configuration. The only element that must be provided by the user is a task unit factory (the grid task will automatically use the default implementation for the other elements if their implementations are not provided). To provide a task unit factory implementation we need to implement two interfaces: GridTaskUnitFactory and GridTaskUnit – and that is almost all you need to do to run an application on the grid!
PrimeGridTaskUnitFactory.java
On line 2 the grid task unit factory takes 3 parameters and creates a new instance of the task unit. Here is the full source code for this task unit:
PrimeGridTaskUnit.java
Now, as we mentioned before the grid task unit is responsible for three main tasks (all of which are generally optional): splitting itself into a sub-grid task unit, aggregating results from sub-grid task units, and executing itself locally (without splitting). To do that one needs to provide an implementation for the following three methods:
Note that for simplicity this example assumes that it will run in a homogenous environment (all computers in the grid are identical) and we do not account for an uneven distribution of prime numbers. Both of these considerations, however, can be easily added. (The example source code shipped with xTier provides for heterogeneous splitting.) What is important to note is that this is the only code that needs to be written to execute our simple example on a single node, two nodes or 100s of nodes. xTier/GRID automatically takes care of the underlying topology management, cluster communication, failure resolution and many other aspects of grid task execution. Most of that functionality, however, is pluggable and more advanced examples can take advantage of custom routing or topology resolution, for example. If you run more than one grid task (which is what happens in reality) xTier/GRID will enable greater utilization of the grid computing resources through smart topology management coupled with such innovative concepts like pluggable dynamic grid taxonomy and task routing.
Executin Grid Task
Most of the work happens in lines 12 to 19 where we prepare the arguments for the grid task call and perform the actual grid task execution (line 19). That is all Java code you need to have for your simple grid application!
Results
Each test was performed for a [0 ... 10,000,000] range and yielded 664579 prime numbers. All results were averaged on 5 runs. Ideal (theoretical) durations were calculated based on 5 nodes run. The following table and charts show the result we obtain for each grid configuration:
Try It Out
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Copyright © 2004-2008 Fitech Laboratories. All rights reserved. Legal and privacy notice. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||