Skip to content

ReadFrom Settings

Mark Paluch edited this page Oct 26, 2020 · 9 revisions

The ReadFrom setting describes how Lettuce routes read operations to replica nodes.

By default, Lettuce routes its read operations in multi-node connections to the upstream node. Reading from the upstream returns the most recent version of the data because write operations are issued to the single upstream node. Reading from upstreams guarantees strong consistency.

You can reduce latency or improve read throughput by distributing reads to replica members for applications that do not require fully up-to-date data.

Be careful if using other ReadFrom settings than UPSTREAM. Settings other than UPSTREAM may return stale data because the replication is asynchronous. Data in the replicas may not hold the most recent data.

Redis Cluster

Redis Cluster is a multi-node operated Redis setup that uses one or more upstream nodes and allows to setup replica nodes. Redis Cluster connections allow to set a ReadFrom setting on connection level. This setting applies for all read operations on this connection.

Example 1. Enable Replica reads with ReadFrom.REPLICA
RedisClusterClient client = RedisClusterClient.create(RedisURI.create("host", 7379));
StatefulRedisClusterConnection<String, String> connection = client.connect();
connection.setReadFrom(ReadFrom.REPLICA);

RedisAdvancedClusterCommands<String, String> sync = connection.sync();
sync.set(key, "value");

sync.get(key); // replica read

connection.close();
client.shutdown();

Upstream/Replica connections ("Master/Slave")

Redis nodes can be operated in a Upstream/Replica setup to achieve availability and performance. Upstream/Replica setups can be run either Standalone or managed using Redis Sentinel. Lettuce allows to use replica nodes for read operations by using the MasterReplica API that supports both Master/Replica setups:

  1. Redis Standalone Upstream/Replica (no failover)

  2. Redis Sentinel Upstream/Replica (Sentinel-managed failover)

The resulting connection uses in any case the primary connection-point to dispatch non-read operations.

Redis Sentinel

Upstream/Replica with Redis Sentinel is very similar to regular Redis Sentinel operations. When the upstream fails over, a replica is promoted by Redis Sentinel to the new upstream and the client obtains the new topology from Redis Sentinel.

Connections to Upstream/Replica require one or more Redis Sentinel connection points and a upstream name. The primary connection point is the Sentinel monitored upstream node.

Example 2. Using ReadFrom with Upstream/Replica and Redis Sentinel
RedisURI sentinelUri = RedisURI.Builder.sentinel("sentinel-host", 26379, "upstream-name").build();
RedisClient client = RedisClient.create();

StatefulRedisMasterReplicaConnection<String, String> connection = MasterReplica.connect(
            client,
            StringCodec.UTF8
            sentinelUri);

connection.setReadFrom(ReadFrom.REPLICA);

connection.sync().get("key"); // Replica read

connection.close();
client.shutdown();

Redis Standalone

Upstream/Replica with Redis Standalone is very similar to regular Redis Standalone operations. A Redis Standalone Upstream/Replica setup is static and provides no built-in failover. Replicas are read from the Redis upstream node’s INFO command.

Connecting to Redis Standalone Upstream/Replica nodes requires connections to use the Redis upstream for the RedisURI. The node used within the RedisURI is the primary connection point.

Example 3. Using ReadFrom with Upstream/Replica and Redis Standalone (Upstream and Replica)
RedisURI upstreamUri = RedisURI.Builder.redis("upstream-host", 6379).build();
RedisClient client = RedisClient.create();

StatefulRedisMasterReplicaConnection<String, String> connection = MasterReplica.connect(
            client,
            StringCodec.UTF8,
            upstreamUri);

connection.setReadFrom(ReadFrom.REPLICA);

connection.sync().get("key"); // Replica read

connection.close();
client.shutdown();

Use Cases for non-upstream reads

The following use cases are common for using non-upstream read settings and encourage eventual consistency:

  • Providing local reads for geographically distributed applications. If you have Redis and application servers in multiple data centers, you may consider having a geographically distributed cluster. Using the NEAREST setting allows the client to read from the lowest-latency members, rather than always reading from the upstream node.

  • Maintaining availability during a failover. Use UPSTREAM_PREFERRED if you want an application to read from the upstream by default, but to allow stale reads from replicas when the upstream node is unavailable. UPSTREAM_PREFERRED allows a "read-only mode" for your application during a failover.

  • Increase read throughput by allowing stale reads If you want to increase your read throughput by adding additional replica nodes to your cluster Use REPLICA to read explicitly from replicas and reduce read load on the upstream node. Using replica reads can highly lead to stale reads.

Read from settings

All ReadFrom settings except UPSTREAM may return stale data because replicas replication is asynchronous and requires some delay. You need to ensure that your application can tolerate stale data.

Setting Description

UPSTREAM

Default mode. Read from the current upstream node.

UPSTREAM_PREFERRED

Read from the upstream, but if it is unavailable, read from replica nodes.

REPLICA

Read from replica nodes.

REPLICA_PREFERRED

Read from the replica nodes, but if none is unavailable, read from the upstream.

NEAREST

Read from any node of the cluster with the lowest latency.

ANY

Read from any node of the cluster.

ANY_REPLICA

Read from any replica of the cluster.

Tip
The latency of the nodes is determined upon the cluster topology refresh. If the topology view is never refreshed, values from the initial cluster nodes read are used.

Custom read settings can be implemented by extending the io.lettuce.core.ReadFrom class.

Clone this wiki locally