How to set up distributed mode
This page explains how to configure Atoti What-If for distributed deployments where data is spread across multiple nodes.
What is distributed mode
In a distributed Atoti Server deployment, data is partitioned across multiple data nodes, with a query node coordinating requests. Atoti What-If supports this architecture by sending simulation operations to all data nodes via REST calls.
When distributed mode is enabled, the starter creates a RestDistributedDatabaseService that:
- Discovers data node addresses from the distributed pivot
- Forwards database operations to all nodes
- Merges query results from multiple nodes
- Handles authentication using JWT tokens
Prerequisites
Before enabling distributed mode:
- Your Atoti Server application must be configured for distribution
- A query node with
IMultiVersionDistributedActivePivotmust be available - JWT authentication must be configured
- Data nodes must expose the Database Service REST API
How to enable distributed mode
Add the following properties to your application.yml:
atoti:
what-if:
distribution:
enabled: true
query-node-name: "MyQueryNode"
The query-node-name must match the name of your query node pivot as configured in your Atoti Server application.
Auto-configured beans
When distribution.enabled: true, the starter creates:
| Bean | Description |
|---|---|
IDistributedQueryResultsMerger |
Merges results from multiple data nodes |
AddressSupplier |
Supplies data node addresses from the distributed pivot |
AuthenticatorSupplier |
Supplies JWT authenticators for REST calls |
RestDistributedDatabaseService |
The distributed database service (marked as @Primary) |
Configuration properties
| Property | Type | Default | Description |
|---|---|---|---|
atoti.what-if.distribution.enabled |
boolean | false |
Enables distributed mode |
atoti.what-if.distribution.query-node-name |
String | "" |
Name of the query node pivot |
atoti.what-if.distribution.create-distributed-service |
boolean | true |
Whether to auto-create RestDistributedDatabaseService |
How to provide a custom address supplier
By default, the starter discovers data node addresses from the distributed pivot. To use a custom address supplier:
@Bean
public AddressSupplier customAddressSupplier() {
return () -> Set.of(
"http://data-node-1:8080/",
"http://data-node-2:8080/",
"http://data-node-3:8080/"
);
}
How to provide a custom authenticator
By default, JWT authentication is used. To provide a custom authenticator:
@Bean
public AuthenticatorSupplier customAuthenticatorSupplier() {
return () -> new MyCustomAuthenticator();
}
How to provide a custom distributed database service
To replace the auto-configured RestDistributedDatabaseService:
- Set
create-distributed-service: falsein your configuration:
atoti:
what-if:
distribution:
enabled: true
query-node-name: "MyQueryNode"
create-distributed-service: false
- Define your custom bean:
@Bean
@Primary
public IDatabaseService customDistributedDatabaseService(
IDistributedQueryResultsMerger resultsMerger,
AddressSupplier addressSupplier,
AuthenticatorSupplier authenticatorSupplier) {
return new MyCustomDistributedDatabaseService(
resultsMerger, addressSupplier, authenticatorSupplier);
}
How to customize result merging
The DefaultDistributedQueryResultsMerger combines query results from all data nodes. To customize merging logic:
@Bean
public IDistributedQueryResultsMerger customResultsMerger() {
return new IDistributedQueryResultsMerger() {
@Override
public JsonDatabaseQueryResult mergeQueryResults(
List<JsonDatabaseQueryResult> results) {
// Custom merge logic
}
// Implement other methods as needed
};
}
Error handling
The RestDistributedDatabaseService throws:
ActiveViamRuntimeExceptionif no data node addresses are availableInternalServiceExceptionif operations on distributed nodes fail
Ensure your error handling accounts for partial failures when some nodes are unreachable.