Use Session Context for Load Balancing
-
The
LoadBalanceBehavior
convention determines whether client sessions are allowed to select the topologies that handle their requests.
When enabled, a session can select a topology bytag
.
Client requests sent by sessions that use the same tag, are handled by the same topology. -
Clients and administrators can use tags to load-balance traffic, e.g. by using the topology tagged "users/1-A" for requests sent by this user.
-
In this page:
LoadBalanceBehavior Usage
By default (or by explicitly setting the LoadBalanceBehavior
and
ReadBalanceBehavior
conventions to None
), the cluster designates
a primary node that all read and write client requests are
sent to.
In case of a failure, the primary node is automatically replaced by another.
The ReadBalanceBehavior convention can be used to change this behavior for read requests, and spread them among all cluster nodes. write requests, however, would still always be sent to the primary node.
With the LoadBalanceBehavior
convention set to UseSessionContext
,
the default behavior can change for write requests as well: sessions
can use a tag
while sending requests, and all the sessions that use
the same tag will share the same primary node in the database topology.
To load-balance requests, you can use different tags.
Consider, for example, a database with three nodes: A
,B
and C
.
If you are using a per-user context, sessions sending their requests with
a users/1-A
tag may be given node B as their primary node (for
both reads and writes), while sessions that send requests with the
users/2-A
tag will be given node C as primary.
Besides allowing the session to select the primary node, RavenDB's behavior is unchanged: replication between database nodes operates normally, and write requests sent to one node are replicated to all other nodes.
Spreading requests between cluster nodes is useful when there is some degree
of separation in your system, and a specific set of sessions typically handles
a specific set of documents.
A common example would be setting the context to the current user or tenant,
allowing the read and write load to spread across cluster nodes on a fair basis.
Node failure is handled normally, and even the failure of a primary node to
handle a particular tag
will not be visible to your code: failover to another
database node will happen automatically and transparently.
LoadBalanceBehavior Options
-
None
Read requests are handled based on the ReadBalanceBehavior convention.
Write requests are handled by the Preferred Node calculated by the client. -
UseSessionContext
- A client session can select the topology that would handle its requests.
The topology is selected bytag
.
Requests that use the same tag, are served by the same topology.
The same nodes are used for read and write requests. - Administrators can disable this feature, overriding a client
LoadBalanceBehavior.UseSessionContext
setting with their ownLoadBalanceBehavior.None
setting. - Administrators can add a hash, to randomize the topology
selected for the client when it uses a tag.
This option may be used in highly unlikely circumstances like the detection of many or all sessions sending requests to the same primary node, if you want to spread the load differently. - Using this option to choose client request-handling topology influences only the client, causing no change in replication or other server functions.
- A client session can select the topology that would handle its requests.
Conflicts may rarely happen, when multiple sessions that use different tags
modify a shared document concurrently. This is handled by RavenDB according
to your conflict resolution strategy.
Examples
Example I
In this example, a client session chooses its topology by tag.
string currentUserID = "usersTopology";
using var store = new DocumentStore
{
Conventions = new DocumentConventions
{
ReadBalanceBehavior = ReadBalanceBehavior.RoundRobin,
LoadBalanceBehavior = LoadBalanceBehavior.UseSessionContext,
LoadBalancerPerSessionContextSelector = db => currentUserID
}
}.Initialize();
using (var session = store.OpenSession())
{
session.Advanced.SessionInfo.SetContext("usersTopology");
session.Load<User>("users/1-A");
}
Example II
In this example a client configuration, including the topology
selection, is placed on the server using
PutClientConfigurationOperation.
store.Maintenance.Send(
new PutClientConfigurationOperation(
new ClientConfiguration
{
ReadBalanceBehavior = ReadBalanceBehavior.RoundRobin,
LoadBalanceBehavior = LoadBalanceBehavior.UseSessionContext,
LoadBalancerContextSeed = 10,
Disabled = false
}));
Example III
In this example a server-wide client configuration, including topology
selection, is placed on the server using
PutServerWideClientConfigurationOperation.
store.Maintenance.Server.Send(new PutServerWideClientConfigurationOperation(
new ClientConfiguration
{
ReadBalanceBehavior = ReadBalanceBehavior.FastestNode,
LoadBalanceBehavior = LoadBalanceBehavior.UseSessionContext,
LoadBalancerContextSeed = 10,
Disabled = false
}
));