Spring Data Redis(Lettuce)のReadFrom.NEARESTはクラスタ構成でのみ有効な件


結論

Spring Data Redis(Lettuce)のReadFrom.NEARESTはクラスタ構成でのみ有効。
Master-Replica構成(Sentinel構成含む)では無効。

根拠

1. Lettuceのドキュメントで確認

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.

2. Lettuceのソースコードで確認

コメントの通り、getNodesメソッドがレイテンシの少ない順にノードを返すのですが、これの呼び出し元がClusterScanSupportのみというところから判断しました。

ReadFrom.java
    /**
     * Descriptor of nodes that are available for the current read operation.
     */
    public interface Nodes extends Iterable<RedisNodeDescription> {

        /**
         * Returns the list of nodes that are applicable for the read operation. The list is ordered by latency.
         *
         * @return the collection of nodes that are applicable for reading.
         *
         */
        List<RedisNodeDescription> getNodes();

    }

そもそもの問題

RedisのMaster-Replica構成。

  • 東京リージョン
    • az-a: Redis(master) + Application(Spring Boot + Spring Data Redis)
    • az-c: Redis(replica) + Application(Spring Boot + Spring Data Redis)
    • az-d: Redis(replica)

AZ間のネットワークレイテンシが大きいので、ApplicationからのRedisの読み取り処理については、同一AZ内のノードから出来るのが望ましい。
※書き込み処理については、masterに対してしか出来ないので、AZ間のネットワークレイテンシは諦めるしかない。

ApplicationにReadFrom.NEARESTを設定すれば、最寄りのRedisノードから読み取り処理してくれそうなのだが、実際は冒頭の結論の通りこれは期待通り動かない。

回避策

RedisStaticMasterReplicaConfigurationでコネクションをセットアップのうえ、ReadFromを下記のように設定する。SentinelConfigurationは不可。

  • 東京リージョン
    • az-a: Redis(master) + Application(ReadFrom.MASTER_PREFERREDを指定。)
    • az-c: Redis(replica) + Application(ReadFrom.REPLICA_PREFERREDを指定。az-dにも行きそうだけど行かない。ノードの設定順に影響されるかも。)
    • az-d: Redis(replica)

これでRedisの読み取り処理については、AZ内に閉じることが出来る。

その他対策

Pipelineを使って、複数コマンドを1回の通信に収めると良さそう(未検証)。

お願い

Jedisや他言語のRedisライブラリがどうなのか教えて欲しいです。