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.
    So load balancing is achieved by assigning a different context 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.

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: 
// ===============================================

const documentStore = new DocumentStore(["serverUrl_1", "serverUrl_2", "..."], "DefaultDB");

// Enable the session-context feature
// If this is not enabled then a context string set in a session will be ignored 
documentStore.conventions.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
documentStore.conventions.loadBalancerPerSessionContextSelector = getDefaultContext;

// Set a seed
// The seed is 0 by default, provide any number to override
documentStore.conventions.loadBalancerContextSeed = 5

documentStore.initialize();
// A customized method for getting a default context string 
const getDefaultContext = (dbName) => {
    // 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:
const 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
const employee = await session.load("employees/1-A");
// Open a session that will use a UNIQUE context string:
const session = documentStore.openSession();

// Call setContext, pass a unique context string for this session
session.advanced.sessionInfo.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
const employee = await session.load("employees/1-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:
// ====================================================================

// Define the client configuration to put on the server
const configurationToSave = {
    // Enable the session-context feature
    // If this is not enabled then a context string set in a session will be ignored 
    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
const putConfigurationOp = new PutClientConfigurationOperation(configurationToSave);

// Execute the operation by passing it to maintenance.send
await 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
// Setting 'loadBalanceBehavior' on the server by sending an operation:
// ====================================================================

// Define the client configuration to put on the server
const configurationToSave = {
    // Enable the session-context feature
    // If this is not enabled then a context string set in a session will be ignored 
    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 ALL databases
const putConfigurationOp = new PutServerWideClientConfigurationOperation(configurationToSave);

// Execute the operation by passing it to maintenance.server.send
await 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

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.