Làm cách nào để kết nối cụm AWS Elasticache Redis với ứng dụng Spring Boot?


8

Tôi có ứng dụng Spring Boot kết nối với cụm Redis, sử dụng Jedis Connection Factory:

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

và đọc danh sách các nút từ 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

Bây giờ chúng tôi muốn chuyển sang Elasticache vì chúng tôi sẽ lưu trữ cụm Redis của chúng tôi trên AWS. Nó sẽ được thực hiện khá dễ dàng. Nếu lib AmazonElastiCache có thể được sử dụng. Sau đó, chúng tôi chỉ có thể kết nối với cụm đàn hồi với thông tin xác thực AWS, kéo các nút có sẵn đưa nó vào danh sách và chuyển nó đến Jedis thay vì mã hóa chúng trong application.yml, như:

//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;
}

Nhưng nhóm DevOps nói rằng họ không thể định cấu hình quyền truy cập AWS trên tất cả các phòng thí nghiệm và họ có lý do cho việc này. Ngoài ra, thay vì kết nối với AWS và kéo tất cả các cụm có sẵn, chúng tôi cần kết nối với một cụm cụ thể bằng URL.

Vì vậy, tôi đã cố gắng chuyển trực tiếp url của cụm Elasticache cho Jedis dưới dạng độc lập và dưới dạng cụm trong cấu hình application.yml. Trong cả hai trường hợp, kết nối được thiết lập, nhưng khi Ứng dụng cố gắng ghi vào Elasticache, nó sẽ bị ngoại lệ 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

Theo như tôi hiểu có nghĩa là Ứng dụng đã cố ghi vào một trong các nút trong Elasticache, nhưng không thể kết nối.

Vì vậy, câu hỏi đặt ra là có cách nào để kết nối với cụm Elasticache Redis từ ứng dụng Spring Boot chỉ bằng URL cụm Elasticache không?

Tôi biết rằng nó có thể thực hiện được nếu sử dụng Elasticache Memecache. Ngoài ra trình điều khiển Jedis không phải là một yêu cầu khó khăn.

Cảm ơn bạn.

Câu trả lời:


2

Sau một số nghiên cứu, chúng tôi đã học được rằng nếu điểm cuối của cụm AWS Elasticache được đặt làm nút trong RedisClusterConfigurationthì trình điều khiển (Jedis hoặc Xà lách) có thể kết nối và tìm tất cả các nút trong cụm Elasticache. Ngoài ra, nếu một trong các nút đi xuống, trình điều khiển có thể giao tiếp với cụm Elasticache thông qua một số nút khác.

Chúng tôi cũng đã chuyển sang trình điều khiển Lettuce trong khi thực hiện nâng cấp này, vì Lettuce là trình điều khiển mặc định được cung cấp trong Spring Boot Redis Started và hỗ trợ các phiên bản Redis mới nhất. Kết nối rau diếp cũng được thiết kế để an toàn cho chủ đề, Jedis thì không.

Mã ví dụ:

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

là "" ****. ***. ****. ****. cache.amazonaws.com: "tên máy chủ cụm đàn hồi?
Santh

vâng đó là tên máy chủ cụm ElastiCache
Marius Jaraminas

0

Lấy cảm hứng từ câu trả lời trên : , hoàn thành mã chi tiết hơn

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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.