AWS Elasticache RedisクラスターをSpring Bootアプリに接続するにはどうすればよいですか?


8

Jedis Connection Factoryを使用してRedisクラスターに接続するSpring Bootアプリがあります。

RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
redisClusterConfiguration.setPassword(redisProperties.getPassword());
jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration);

そして、application.ymlからノードのリストを読み取ります:

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    timeout: 300s
    cluster:
      nodes: 127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382

とにかく、AWSでRedisクラスターをホストしているので、Elasticacheに切り替えます。とても簡単にできます。AmazonElastiCache libを使用できる場合。次に、AWS資格情報でElasticacheクラスターに接続し、利用可能なノードをプルしてリストに入れ、次のようにapplication.ymlでハードコーディングする代わりにJedisに渡します。

//get cache cluster nodes using AWS api
private List<String> getClusterNodes(){
    AmazonElastiCache client = AmazonElastiCacheClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
    DescribeCacheClustersRequest describeCacheClustersRequest = new DescribeCacheClustersRequest();
    describeCacheClustersRequest.setShowCacheNodeInfo(true);
    List<CacheCluster> cacheClusterList = client.describeCacheClusters(describeCacheClustersRequest).getCacheClusters();
    List<String> nodeList = new ArrayList<>();
    try {
        for (CacheCluster cacheCluster : cacheClusterList) {
            for(CacheNode cacheNode :cacheCluster.getCacheNodes()) {
                String nodeAddr = cacheNode.getEndpoint().getAddress() + ":" +cacheNode.getEndpoint().getPort();
                nodeList.add(nodeAddr);
            }
        }
    }
    catch(Exception e) {
        e.printStackTrace();
    }
    return nodeList;
}

しかし、DevOpsチームは、すべてのラボでAWSアクセスを設定することはできず、それには理由があると述べました。また、AWSに接続して利用可能なすべてのクラスターをプルする代わりに、URLで特定のクラスターに接続する必要があります。

そのため、ElasticacheクラスターのURLをスタンドアロンとして、およびapplication.yml構成のクラスターとして直接Jedisに渡そうとしました。どちらの場合も接続は確立されますが、AppがElasticacheに書き込もうとすると、MOVED例外が発生します。

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.data.redis.ClusterRedirectException: Redirect: slot 1209 to 10.10.10.011:6379.; nested exception is redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 1209 10.10.10.102:6379

私が理解しているのは、アプリがElasticacheのノードの1つに書き込もうとしたが、接続できなかったことを意味します。

それで問題は、ElasticacheクラスターURLのみを使用してSpring BootアプリからElasticache Redisクラスターに接続する方法があるのでしょうか?

Elasticache Memecacheを使用すれば実行可能であることはわかっています。また、Jedisドライバーは難しい要件ではありません。

ありがとうございました。

回答:


2

いくつかの調査の結果、AWS Elasticacheクラスターのエンドポイントがノードとして設定されている場合、RedisClusterConfigurationドライバー(JedisまたはLettuce)がElasticacheクラスター内のすべてのノードに接続して検出できることがわかりました。また、ノードの1つがダウンした場合、ドライバーは他のノードを介してElasticacheクラスターと通信できます。

LettuceはSpring Boot Redis Startedで提供されるデフォルトのドライバーであり、最新のRedisバージョンをサポートしているため、このアップグレードの作業中にも、Lettuceドライバーに移行しました。レタスの接続もスレッドセーフになるように設計されていますが、ジェディスはそうではありません。

コード例:

List<String> nodes = Collections.singletonList("****.***.****.****.cache.amazonaws.com:6379");
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(nodes);
return new LettuceConnectionFactory(clusterConfiguration);

"" ****。***。****。****。cache.amazonaws.com: "はElasticクラスターホスト名ですか?
Santh

はいthats ElastiCacheクラスターのホスト名
Marius Jaraminas

0

上記の回答から発想を得た:より詳細なコードを完成させる

List<String> nodes = Collections.singletonList("<cluster-host-name>:<port>");
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(nodes);

ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder().closeStaleConnections(true)
            .enableAllAdaptiveRefreshTriggers().build();

ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder().autoReconnect(true)
            .topologyRefreshOptions(topologyRefreshOptions).validateClusterNodeMembership(false)
            .build();
//If you want to add tuning options
LettuceClientConfiguration  lettuceClientConfiguration = LettuceClientConfiguration.builder().readFrom(ReadFrom.REPLICA_PREFERRED).clientOptions(clusterClientOptions).build();

LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
lettuceConnectionFactory.afterPropertiesSet();//**this is REQUIRED**
StringRedisTemplate redisTemplate = new StringRedisTemplate(lettuceConnectionFactory);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.