programing

AWS Elasticache Redis 클러스터를 Spring Boot 앱에 연결하는 방법은?

closeapi 2023. 10. 13. 22:14
반응형

AWS Elasticache Redis 클러스터를 Spring Boot 앱에 연결하는 방법은?

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로 전환하고 싶습니다.그것은 꽤 쉽게 이루어질 것입니다.Amazon ElastiCache 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에게 직접 전달하려고 했습니다.두 경우 모두 연결이 설정되지만 앱이 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의 노드 중 하나에 글을 쓰려고 했지만 연결할 수 없었다는 뜻입니다.

그렇다면 문제는 Elasticache 클러스터 URL만 사용하여 Spring Boot 앱에서 Elasticache Redis 클러스터에 연결하는 방법이 있습니까?

Elasticache Memecache를 사용하면 가능하다고 알고 있습니다.또한 제디스 드라이버는 어려운 요구사항이 아닙니다.

감사해요.

몇 가지 조사 끝에 AWS Elastache 클러스터 엔드포인트가 노드로 설정되어 있는 경우RedisClusterConfiguration그러면 드라이버(제디스 또는 양상추)가 Elasticache 클러스터의 모든 노드를 연결하고 찾을 수 있습니다.또한 노드 중 하나가 다운되면 드라이버는 다른 노드를 통해 Elasticache 클러스터와 통신할 수 있습니다.

Spring Boot Redis Started에서 기본 드라이버로 제공되고 최신 Redis 버전을 지원하기 때문에 이번 업그레이드 작업도 진행하면서 Laccute 드라이버로 마이그레이션했습니다.상추 연결 부분도 나사산에 안전하도록 설계되어 있습니다, 제디스는 그렇지 않습니다.

코드 예제:

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

위의 답변에서 영감을 얻어: 더 자세한 코드를 완성

 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(clusterConfiguration, lettuceClientConfiguration);
 lettuceConnectionFactory.afterPropertiesSet();//**this is REQUIRED**
 StringRedisTemplate redisTemplate = new StringRedisTemplate(lettuceConnectionFactory);

언급URL : https://stackoverflow.com/questions/59289359/how-to-connect-aws-elasticache-redis-cluster-to-spring-boot-app

반응형