Skip to main content

Load balance behavior

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.

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:
var documentStore = new DocumentStore
{
Urls = new[] {"ServerURL_1", "ServerURL_2", "..."},
Database = "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
LoadBalanceBehavior = LoadBalanceBehavior.UseSessionContext,

// Assign a method that sets the default context string
// This method will be called to provide a default context string for sessions that do not set one explicitly
// A sample GetDefaultContext method is defined below
LoadBalancerPerSessionContextSelector = GetDefaultContext,

// Set a seed
// The seed is 0 by default, provide any number to override
LoadBalancerContextSeed = 5
}
}.Initialize();
// A customized method for getting a default context string

public const string DefaultContextStringKey = "DefaultContextString";

private string GetDefaultContext(string dbName)
{
// Get the string set by the web application elsewhere.
var ctx = System.Web.HttpContext.Current;
if (ctx == null)
{
// return a safe default
return dbName;
}

// Return the context set elsewhere or default to the dbName
return (ctx.Items[DefaultContextStringKey] as string) ?? dbName;
}

Session usage:

// Open a session that will use the DEFAULT store values:
using (var session = documentStore.OpenSession())
{
// For all Read & Write requests made in this session,
// node to access is calculated from string & seed values defined on the store
var employee = session.Load<Employee>("employees/1-A");
}
// Open a session that will use a UNIQUE context string:
using (var session = documentStore.OpenSession())
{
// Call 'SetContext' to assign a dedicated context string for this session.
// For example: "team/9-A", representing the team that the employees loaded in this session belong to.
session.Advanced.SessionInfo.SetContext("team/9-A");

// For all Read & Write requests made in this session, including the following load calls,
// a node to access is calculated from the unique string & the seed defined on the store
var employee1 = session.Load<Employee>("employees/1-A");
var employee2 = session.Load<Employee>("employees/3-A");
}

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 session.Advanced.SessionInfo.SetContext
    • or, on the document store, set a default value for - LoadBalancerPerSessionContextSelector

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:
using (documentStore)
{
// Define the client configuration to put on the server
var configurationToSave = new ClientConfiguration
{
// Enable the session-context feature
// If this is not enabled then a context string set in a session will be ignored
LoadBalanceBehavior = LoadBalanceBehavior.UseSessionContext,

// Set a seed
// The seed is 0 by default, provide any number to override
LoadBalancerContextSeed = 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
Disabled = false
};

// Define the put configuration operation for the DEFAULT database
var 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
}

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 and Write requests among cluster nodes can be beneficial when a set of sessions consistently handles a specific group of documents or related data. By setting a context string per session, you can ensure that similar sessions (e.g., sessions for a specific user, tenant, or team) are routed to the same node, while other sessions are routed to different nodes - achieving effective load distribution.

  • In scenarios where optimistic concurrency is enabled, routing sessions for the same entity to the same node can help reduce Write conflicts, since concurrent updates tend to be coordinated on the same node. The node handling the write is also more likely to have the latest version of the document, which helps avoid cross-node conflicts.

  • Once load balancing is configured to use the session context, if many sessions still end up being routed to the same node, you can introduce additional distribution by adjusting the context seed on the store.

In this article