MapReduce model
SchedulerX MapReduce distributes batch data processing across connected workers through a simple Java API. Instead of importing data into a big data platform such as Hadoop or Spark, you process data in place -- splitting work into subtasks that run in parallel on your existing application nodes.
Compared to traditional big data frameworks, SchedulerX MapReduce offers:
No data migration: Process data directly in your databases without building an ETL pipeline to a separate cluster.
Fast startup: Tasks start in seconds, not minutes.
No infrastructure overhead: No additional storage or computing resources beyond your existing workers.
Simple programming model: Extend
MapJobProcessororMapReduceJobProcessorand implement two to three methods.
How it works
Map vs. MapReduce: pick the right processor
SchedulerX provides two processor interfaces. Choose based on whether you need to aggregate results after all subtasks complete.
| Processor | Use case | Reduce phase |
|---|---|---|
MapJobProcessor | Distribute work across workers. Each subtask runs independently. | No |
MapReduceJobProcessor | Distribute work, then aggregate results or trigger downstream actions after all subtasks finish. | Yes |
If you do not need a reduce phase, use MapJobProcessor. The reduce phase caches all subtask results on the master node, which increases memory pressure.
Execution flow
All MapReduce jobs follow the same pattern:
SchedulerX invokes
process()on the master node. The master detects that it is the root task.The root task splits work into subtasks and calls
map()to distribute them across workers.Each worker receives a subtask, checks the task name, and runs the corresponding processing logic.
(MapReduce only) After all subtasks finish, SchedulerX calls
reduce()on the master node to aggregate results.
You can call map() multiple times to create multi-level task trees, for example: database shards -> table shards -> page ranges.
API reference
MapJobProcessor methods
| Method | Description | Required |
|---|---|---|
process(JobContext context) | Entry point for task execution. Call isRootTask(context) to determine whether to distribute subtasks or process a subtask. Returns ProcessResult. | Yes |
map(List<? extends Object> taskList, String taskName) | Distribute a batch of subtasks to workers. Can be called multiple times to create multi-level task trees. If taskList is empty, an error is returned. Returns ProcessResult. | Yes |
kill(JobContext context) | Called when a job is stopped from the console. Implement cleanup or interruption logic here. | No |
MapReduceJobProcessor methods
MapReduceJobProcessor includes all methods from MapJobProcessor, plus the following:
| Method | Description | Required |
|---|---|---|
reduce(JobContext context) | Runs on the master node after all subtasks complete. Use context.getTaskStatuses() and context.getTaskResults() to access subtask outcomes. Common uses: aggregate data, send notifications, or pass data to downstream workflow nodes. | Yes |
runReduceIfFail(JobContext context) | Specifies whether to call the reduce method if a subtask fails. By default, reduce is executed even if a subtask fails. | No |
How the reduce flow works:
Each subtask returns a result through
return new ProcessResult(true, result), whereresultis a string (for example, an order ID or a computed value).After all subtasks finish, SchedulerX calls
reduceon the master node.Inside
reduce, callcontext.getTaskStatuses()for completion statuses andcontext.getTaskResults()for the result strings.
The reduce phase caches all subtask results on the master node. To avoid out-of-memory errors, keep the number of subtasks and the size of each result value small. If you do not need result aggregation, use MapJobProcessor instead.
Limits
| Constraint | Limit |
|---|---|
| Maximum task size | 64 KB |
Maximum ProcessResult result field size | 1,000 bytes |
| Reduce memory impact | All subtask results are cached on the master node. Keep subtask count and result sizes small. |
| Idempotency requirement | SchedulerX may run a subtask more than once during a failover. Design subtask logic to be idempotent. |
Create a MapReduce job
Log on to the SchedulerX console.
In the left-side navigation pane, click Task Management.
On the Task Management page, click Create task.
In the Create Task panel, set Task Type to Java and Execution Mode to MapReduce.
Configure the parameters in the Advanced Configuration section.
Advanced configuration parameters
| Parameter | Description |
|---|---|
| distribution policy | How subtasks are assigned to workers. Polling Scheme (default): distributes an equal number of subtasks to each worker. Best when subtask processing times are similar. Optimal Load Policy: the master node monitors worker load and routes subtasks accordingly. Best when processing times vary across subtasks or workers. Requires agent version 1.10.3 or later. |
| Number of single-machine concurrent subtasks | Number of threads each worker uses to run subtasks. Default: 5. Increase for faster throughput; decrease if downstream systems cannot handle the load. |
| Number of failed retries of subtasks | Number of automatic retries for a failed subtask. Default: 0 (no retry). |
| Sub-task failure retry interval | Seconds between retry attempts. Default: 0. |
| Subtask Failover Strategy | When enabled, a subtask is reassigned to a different worker after the original worker fails to execute it and is stopped. Because this can cause duplicate execution, make sure subtask logic is idempotent. Requires agent version 1.8.12 or later. |
| The master node participates in the execution | When enabled, the master node also runs subtasks. Requires at least two workers. Disable this for jobs with a very large number of subtasks to reduce master node load. Requires agent version 1.8.12 or later. |
| Subtask distribution method | Push model: the master distributes subtasks evenly to workers. Pull model: workers pull subtasks on demand, which supports dynamic scale-up. The Wooden Bucket Theory is not applicable to this model. In pull mode, all pending subtasks are cached on the master node. To avoid memory issues, do not distribute more than 10,000 subtasks at a time. |
For a complete list of parameters, see Advanced parameters for job management.
Examples
Scan a single table by ID range
Scan a single table by hash bucket
Scan sharded databases and tables
Distribute messages with reduce
Distribute messages and aggregate results in reduce
Best practices
Choose the simplest processor: Use
MapJobProcessorunless you need result aggregation. The reduce phase adds memory overhead on the master node.Design for idempotency: Subtasks may run more than once during failover. Use unique IDs or idempotency keys to prevent duplicate side effects.
Tune PAGE_SIZE for your workload: Larger pages mean fewer subtasks but higher retry cost on failure. Smaller pages improve parallelism but increase scheduling overhead.
Handle errors from map(): If the task list is empty,
map()returns an error. Validate your task list before callingmap()in production code.Monitor master node memory: When using reduce or pull mode, subtask data is cached on the master node. In pull mode, do not distribute more than 10,000 subtasks at a time.
Use descriptive task names: When building multi-level task trees, use names like
DbTask,TableTask, andPageTaskto route subtasks to the correct processing branch.
For architecture details, scheduling internals, and performance tuning guidance, see Principles and best practices for SchedulerX 2.0 distributed computing.