【问题标题】:How do I connect to an AWS ElastiCache for Redis Cluster using Jedis?如何使用 Jedis 连接到 AWS ElastiCache for Redis 集群?
【发布时间】:2022-02-13 22:35:58
【问题描述】:

以前,我们使用的是通过 AWS ElastiCache 禁用集群模式的 Redis。

我们使用 Jedis 的 Java 代码指向主要的单节点端点,该端点用于读取和写入。

我们现在启用了集群模式。

我们现在已将代码更改为指向新 Redis 集群的配置端点,但它现在在接收请求时抛出错误,见下文:

Redis 不可用。继续使用 Queue requestMessage 代替。 org.springframework.data.redis.ClusterRedirectException: Redirect: slot 2356 to [ipaddress]:6379.;嵌套异常是 redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 2356 [ipaddress]:6379

我们的配置代码如下:

    @Bean(name = "redisTemplate")
    public RedisTemplate<String, String> getRedisTemplate(JedisConnectionFactory jedisConnectionFactory) {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(jedisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    JedisConnectionFactory jedisConnectionFactory(Configuration config) {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setHostName(config.get(HOST));
        jedisConnectionFactory.setPort(config.getInt(PORT));
        jedisConnectionFactory.setUsePool(true);
        jedisConnectionFactory.setPoolConfig(createJedisPoolConfig(config));
        jedisConnectionFactory.afterPropertiesSet();
        return jedisConnectionFactory;
    }

    JedisPoolConfig createJedisPoolConfig(Config config) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(config.getInt(MAX, 8));
        poolConfig.setMaxIdle(config.getInt(MAXIDLE, 8));
        poolConfig.setMinIdle(config.getInt(MINIDLE, 1));
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        return poolConfig;
    }

不应该只是将 Jedis 更改为指向配置端点就足够了吗?

我需要更改代码中的任何内容吗?

【问题讨论】:

  • 不,您的假设是正确的,端点需要更改,但客户端还需要知道它正在连接到集群。在这种情况下,您需要使用JedisCluster 来发现 Redis 节点。您收到MOVED,因为 Redis 集群告诉客户端正在请求的数据已重新分片到另一个节点,但客户端不知道正在使用集群,因此还有任何其他节点和/或如何连接到他们甚至能够获取数据。
  • 只需将一个指向 AWS 配置端点的节点添加到集群的集合中,Jedis 就会自动发现其他节点 - 然后按预期使用。这行得通吗?
  • 如果使用集群,还要确保您使用的是最新版本的 Jedis。 JedisConnectionFactory 也有一个 cluster override,您可以使用它来代替池。
  • 您好@ErmiyaEskandary,非常感谢您的回复。我是否正确地说我只需要执行以下操作:(1)修改代码以使用 JedisCluster,(2)只需引用节点端点之一即可启用所有节点的自动发现不需要使用配置端点?感谢大家的指导!
  • 不客气 - 您需要执行 (1) 但是对于 (2),您只需引用配置端点,而不是节点。 Jedis 集群将自动发现节点。让我知道它是否有效。

标签: java amazon-web-services redis jedis cluster-mode


【解决方案1】:

不应该只是将 Jedis 更改为指向配置端点就足够了吗?

不,因为 Redis 客户端 - 在本例中为 Jedis - 需要知道它正在连接到集群,但目前没有。

您收到MOVED,因为 Redis 集群告诉客户端正在请求的数据现在已“重新分片”到另一个节点。然而,Jedis 不知道正在使用集群,因此还有其他节点,因此甚至无法连接到它们来检索数据。

我需要更改代码中的任何内容吗?

您需要使用 JedisCluster 而不是 JedisPool 来发现 Redis 节点并在代码库中进行其他相关更改。

注意只需要引用配置端点:

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();

jedisClusterNodes.add(new HostAndPort(CONFIGURATION_ENDPOINT, 6379));

try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes)) {
// ...
}

【讨论】:

    猜你喜欢
    • 2018-12-29
    • 2019-09-12
    • 2020-07-24
    • 2015-10-13
    • 2017-12-27
    • 2020-04-04
    • 2015-11-21
    • 2020-03-31
    • 1970-01-01
    相关资源
    最近更新 更多