如何将AWS Elasticache Redis集群连接到Spring Boot应用程序?

15

我有一个Spring Boot应用程序,它使用Jedis Connection Factory连接到Redis集群:

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

现在我们想要切换到Elasticache,因为我们已经在AWS上托管了我们的Redis集群。 这将非常容易实现。如果可以使用AmazonElastiCache库的话。 然后我们就可以使用AWS凭证连接到Elasticache集群,获取可用节点并将其放入列表中,而不是硬编码在application.yml文件中,如下所示:

//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访问权限,并且他们有理由这样做。而且,我们需要通过URL连接到特定的Elasticache集群,而不是连接到AWS并获取所有可用集群。

所以我尝试直接将Elasticache集群URL传递给Jedis作为独立项和应用程序.yml配置中的集群。在两种情况下都建立了连接,但当应用程序尝试写入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 是可行的。此外,Jedis驱动程序不是硬性要求。

谢谢。

2个回答

9

经过一些研究,我们了解到如果将AWS Elasticache集群端点设置为 RedisClusterConfiguration 中的节点,则驱动程序(Jedis或Lettuce)能够连接并找到Elasticache集群中的所有节点。另外,如果其中一个节点关闭,则驱动程序能够通过其他节点与Elasticache集群通信。

在此升级期间,我们还迁移到了Lettuce驱动程序,因为它是Spring Boot Redis Starter提供的默认驱动程序,并支持最新的Redis版本。Lettuce连接也被设计成线程安全的,而Jedis则不是。

代码示例:

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

“****...***.cache.amazonaws.com:” 是 Elastic 集群的主机名吗? - Ram

3
参考上面回答:完善更详细的代码
 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);

afterPropertiesSet is required, because you seems to be not using LettuceConncectionFactory as a @Bean - heroin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接