Linearizable Read from Followers Developer Guide
Ratis supports linearizable reads, which allows clients to read the most up-to-date committed data from any server in the cluster, including followers. This can significantly improve read throughput and reduce the load on the leader.
Enabling Linearizable Reads
To enable linearizable reads, you must set the raft.server.read.option
property to LINEARIZABLE
in your RaftProperties
when creating the RaftServer
.
import org.apache.ratis.server.RaftServerConfigKeys;
import org.apache.ratis.conf.RaftProperties;
// Create a RaftProperties object
RaftProperties properties = new RaftProperties();
// Enable linearizable reads
RaftServerConfigKeys.Read.setOption(properties, RaftServerConfigKeys.Read.Option.LINEARIZABLE);
// Build your RaftServer with the updated properties
RaftServer server = RaftServer.newBuilder()
// ... other builder configurations
.setProperties(properties)
.build();
Sending Read Requests
Once linearizable reads are enabled on the server, you can send read requests from the client using the standard sendReadOnly
method. Ratis will automatically route the request to an appropriate server (leader or follower) to ensure linearizable consistency.
Asynchronous Read
import org.apache.ratis.client.api.AsyncApi;
import org.apache.ratis.protocol.Message;
import org.apache.ratis.protocol.RaftClientReply;
import java.util.concurrent.CompletableFuture;
// ...
AsyncApi asyncApi = client.async();
CompletableFuture<RaftClientReply> replyFuture = asyncApi.sendReadOnly(Message.valueOf("your-read-only-message"));
Blocking Read
import org.apache.ratis.client.api.BlockingApi;
import org.apache.ratis.protocol.Message;
import org.apache.ratis.protocol.RaftClientReply;
import java.io.IOException;
// ...
BlockingApi blockingApi = client.io();
try {
RaftClientReply reply = blockingApi.sendReadOnly(Message.valueOf("your-read-only-message"));
// process reply
} catch (IOException e) {
// handle exception
}
Non-Linearizable Reads
Even with linearizable reads enabled, you can still opt for a non-linearizable read if you do not require the strongest consistency guarantee. This can be useful for latency-sensitive applications where a slightly stale read is acceptable.
To perform a non-linearizable read, use the sendReadOnlyNonLinearizable
method.
Asynchronous Non-Linearizable Read
CompletableFuture<RaftClientReply> replyFuture = asyncApi.sendReadOnlyNonLinearizable(Message.valueOf("your-read-only-message"));
Blocking Non-Linearizable Read
try {
RaftClientReply reply = blockingApi.sendReadOnlyNonLinearizable(Message.valueOf("your-read-only-message"));
// process reply
} catch (IOException e) {
// handle exception
}