Skip to content
Visit booth 3171 at Google Cloud Next to see how to unlock real-time decisions at scaleMore info

Best practices

Enable Client Log

Each AerospikeClient instance runs a background cluster tend thread that periodically polls all nodes for cluster status. This background thread generates log messages that reflect node additions/removal and any errors when retrieving node status, peers, partition maps and racks. It’s critical that user applications enable this log to receive these important messages.

See Enable Log.

Clients

Use AerospikeClient for sync applications. Use AsyncClient for async applications. AsyncClient inherits from AerospikeClient, so sync commands are supported in AsyncClient as well.

Share Client Instance

Each AerospikeClient/AsyncClient instance spawns a maintenance thread that periodically makes info requests to all server nodes for cluster status. Multiple client instances create additional load on the server. Use only one client instance per cluster in an application and share that instance among multiple threads. The clients are thread-safe.

Set Maximum Connections

Set ClientPolicy.maxConnsPerNode and/or AsyncClientPolicy.asyncMaxConnsPerNode to the maximum number of connections allowed (default 100) per server node. Sync and async connections are tracked separately. The number of connections used per node depends on concurrent commands in progress plus sub-commands used for parallel multi-node commands (batch, scan, and query). One connection will be used for each command. A request will fail if the maximum number of connections would be exceeded.

User-Defined Key

By default, the user-defined key is not stored on the server. It is converted to a hash digest which is used to identify a record. If the user-defined key must persist on the server, use one of the following methods:

  • Set WritePolicy.sendKey to true. The key is sent to the server for storage on writes, and retrieved on multi-record scans and queries.
  • Explicitly store and retrieve the user-defined key in a bin.

Avoid Value/Bin Generic Object Constructors

Do not use Value or Bin constructors that take in an object. These constructors are slower than hard-coded constructors, as the object must be queried for its real type. Also, they use the default C# serializer, which is the slowest of all serialization implementations. It is best to serialize the object with an optimal serializer, and use the byte[] constructor.

Replace Mode

In cases where all record bins are created or updated by a command, enable Replace mode on the command to increase performance. The server then does not have to read the old record before updating. Do not use Replace mode when updating a subset of bins.

WritePolicy policy = new WritePolicy();
policy.recordExistsAction = RecordExistsAction.REPLACE;
client.Put(policy, key, bins);

Policy

Each database command takes in a policy as the first argument. If the policy is identical for a group of commands, reuse them instead of instantiating policies for each command.

Also, set policy defaults in ClientPolicy and pass in a null policy on each command.

ClientPolicy policy = new ClientPolicy();
policy.readPolicyDefault.socketTimeout = 50;
policy.readPolicyDefault.totalTimeout = 110;
policy.readPolicyDefault.sleepBetweenRetries = 10;
policy.writePolicyDefault.socketTimeout = 200;
policy.writePolicyDefault.totalTimeout = 450;
policy.writePolicyDefault.sleepBetweenRetries = 50;
AerospikeClient client = new AerospikeClient(policy, "hostname", 3000);
client.Put(null, new Key("test", "set", 1), new Bin("bin", 5));

If a policy needs to change from the default (such as setting an expected generation), create a new policy that copies the default policy (copy on write). This avoids the case where shared policy instance modifications affect other commands running in parallel.

public void PutIfGeneration(Key key, int generation, Bin... bins) {
WritePolicy policy = new WritePolicy(client.writePolicyDefault);
policy.generationPolicy = GenerationPolicy.EXPECT_GEN_EQUAL;
policy.generation = generation;
client.Put(policy, key, bins);
}

Circuit Breaker

Employ a circuit breaker that activates when a maximum error count is reached for a node and rejects requests to that node until the specified error window expires. The following ClientPolicy fields can create a circuit breaker.

maxErrorRate

Maximum number of errors allowed per node per errorRateWindow. Errors include connection errors, timeouts and device overload. If maximum errors are reached, further requests to that node are retried to another node depending on replica policy. If maxRetries are exhausted, a backoff exception AerospikeException.Backoff is thrown with error code ResultCode.MAX_ERROR_RATE.

errorRateWindow

The number of cluster tend iterations that defines the window for maxErrorRate. One tend iteration is defined as the tend interval (default 1 second) plus the time to tend all nodes. At the end of the window, the error count is reset to zero and backoff state is removed on all nodes.

The user application could optionally use a fallback cluster to handle traffic when the circuit breaker is employed.

Close RecordSet/ResultSet

RecordSet/ResultSet query iterators should always be closed after the iterator is no longer used. Failure to close the iterator when an exception occurs while processing query results may cause the query buffer to fill up and prevent server nodes from completing the query.

using (RecordSet rs = client.Query(null, stmt)) {
while (rs.Next()) {
...
}
}

or

RecordSet rs = client.Query(null, stmt);
try {
while (rs.Next()) {
...
}
}
finally {
rs.Close();
}

Operate

Use AerospikeClient.Operate() to batch multiple operations (add/get) on the same record in a single call.

Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?