Load balance behavior
-
The
loadBalanceBehavior
configuration allows you to specify which sessions should communicate with the same node. -
Sessions that are assigned the same context will have all their Read & Write requests routed to the same node. Gain load balancing by assigning different contexts to different sessions.
LoadBalanceBehavior options
None
(default option)
-
Requests will be handled based on the
ReadBalanceBehavior
configuration.
See the conditional flow described in Client logic for choosing a node.- Read requests:
The client will calculate the target node from the configured ReadBalanceBehavior Option. - Write requests:
Will be sent to the preferred node.
The data will then be replicated to all the other nodes in the database group.
- Read requests:
UseSessionContext
-
Load-balance
-
When this option is enabled, the client will calculate the target node from the session-id.
The session-id is hashed from a context string and an optional seed given by the user.
The context string together with the seed are referred to as "The session context". -
Per session, the client will select a node from the topology list based on this session-context.
So sessions that use the same context will target the same node. -
All Read & Write requests made on the session (i.e a query or a load request, etc.)
will address this calculated node.
Read & Write requests that are made on the store (i.e. executing an operation)
will go to the preferred node. -
All Write requests will be replicated to all the other nodes in the database group as usual.
-
-
Failover
- In case of a failure, the client will try to access the next node from the topology nodes list.
Initialize LoadBalanceBehavior on the client
-
The
LoadBalanceBehavior
convention can be set on the client when initializing the Document Store.
This will set the load balance behavior for the default database that is set on the store. -
This setting can be overriden by setting 'LoadBalanceBehavior' on the server, see below.
Initialize conventions:
// Initialize 'LoadBalanceBehavior' on the client:
$documentStore = new DocumentStore(["ServerURL_1", "ServerURL_2", "..."], "DefaultDB");
$conventions = new DocumentConventions();
// Enable the session-context feature
// If this is not enabled then a context string set in a session will be ignored
$conventions->setLoadBalanceBehavior(LoadBalanceBehavior::useSessionContext());
// Assign a method that sets the default context string
// This string will be used for sessions that do Not provide a context string
// A sample GetDefaultContext method is defined below
$conventions->setLoadBalancerPerSessionContextSelector(\Closure::fromCallable([$this, 'GetDefaultContext']));
// Set a seed
// The seed is 0 by default, provide any number to override
$conventions->setLoadBalancerContextSeed(5);
$documentStore->setConventions($conventions);
$documentStore->initialize();
// A customized method for getting a default context string
private function GetDefaultContext(string $dbName): string
{
// Method is invoked by RavenDB with the database name
// Use that name - or return any string of your choice
return "DefaultContextString";
}
Session usage:
// Open a session that will use the DEFAULT store values:
$session = $documentStore->openSession();
try {
// For all Read & Write requests made in this session,
// node to access is calculated from string & seed values defined on the store
$employee = $session->load(Employee::class, "employees/1-A");
} finally {
$session->close();
}
// Open a session that will use a UNIQUE context string:
$session = $documentStore->openSession();
try {
// Call SetContext, pass a unique context string for this session
$session->advanced()->getSessionInfo()->setContext("SomeOtherContext");
// For all Read & Write requests made in this session,
// node to access is calculated from the unique string & the seed defined on the store
$employee = $session->load(Employee::class, "employees/1-A");
} finally {
$session->close();
}
Set LoadBalanceBehavior on the server
Note:
-
Setting the load balance behavior on the server, either by an Operation or from the Studio,
only 'enables the feature' and sets the seed. -
For the feature to be in effect, you still need to define the context string itself:
- either, per session, call the advanced
setContext
method - or, set a default document store value using
setLoadBalancerPerSessionContextSelector
- either, per session, call the advanced
Set LoadBalanceBehavior on the server - by operation:
-
The
LoadBalanceBehavior
configuration can be set on the server by sending an operation. -
The operation can modify the default database only, or all databases - see examples below.
-
Once configuration on the server has changed, the running client will get updated with the new settings.
See keeping client up-to-date.
// Setting 'LoadBalanceBehavior' on the server by sending an operation:
$documentStore = new DocumentStore();
try {
// Define the client configuration to put on the server
$configurationToSave = new ClientConfiguration();
// Enable the session-context feature
// If this is not enabled then a context string set in a session will be ignored
$configurationToSave->setLoadBalanceBehavior(LoadBalanceBehavior::useSessionContext());
// Set a seed
// The seed is 0 by default, provide any number to override
$configurationToSave->setLoadBalancerContextSeed(10);
// NOTE:
// The session's context string is Not set on the server
// You still need to set it on the client:
// * either as a convention on the document store
// * or pass it to 'SetContext' method on the session
// Configuration will be in effect when Disabled is set to false
$configurationToSave->setDisabled(false);
// Define the put configuration operation for the DEFAULT database
$putConfigurationOp = new PutClientConfigurationOperation($configurationToSave);
// Execute the operation by passing it to Maintenance.Send
$documentStore->maintenance()->send($putConfigurationOp);
// After the operation has executed:
// all Read & Write requests, per session, will address the node calculated from:
// * the seed set on the server &
// * the session's context string set on the client
} finally {
$documentStore->close();
}
// Setting 'LoadBalanceBehavior' on the server by sending an operation:
$documentStore = new DocumentStore();
try {
// Define the client configuration to put on the server
$configurationToSave = new ClientConfiguration();
// Enable the session-context feature
// If this is not enabled then a context string set in a session will be ignored
$configurationToSave->setLoadBalanceBehavior(LoadBalanceBehavior::useSessionContext());
// Set a seed
// The seed is 0 by default, provide any number to override
$configurationToSave->setLoadBalancerContextSeed(10);
// NOTE:
// The session's context string is Not set on the server
// You still need to set it on the client:
// * either as a convention on the document store
// * or pass it to 'SetContext' method on the session
// Configuration will be in effect when Disabled is set to false
$configurationToSave->setDisabled(false);
// Define the put configuration operation for ALL databases
$putConfigurationOp = new PutServerWideClientConfigurationOperation($configurationToSave);
// Execute the operation by passing it to Maintenance.Server.Send
$documentStore->maintenance()->server()->send($putConfigurationOp);
// After the operation has executed:
// all Read & Write requests, per session, will address the node calculated from:
// * the seed set on the server &
// * the session's context string set on the client
} finally {
$documentStore->close();
}
Set LoadBalanceBehavior on the server - from Studio:
-
The
LoadBalanceBehavior
configuration can be set from the Studio's Client Configuration view.
Setting it from the Studio will set this configuration directly on the server. -
Once configuration on the server has changed, the running client will get updated with the new settings.
See keeping client up-to-date.
When to use
-
Distributing Read & Write requests among the cluster nodes can be beneficial
when a set of sessions handle a specific set of documents or similar data.
Load balancing can be achieved by routing requests from the sessions that handle similar topics to the same node, while routing other sessions to other nodes. -
Another usage example can be setting the session's context to be the current user.
Thus spreading the Read & Write requests per user that logs into the application. -
Once setting the load balance to be per session-context,
in the case when detecting that many or all sessions send requests to the same node,
a further level of node randomization can be added by changing the seed.