Azure Redis SSL 集群 + Lettuce Java(编辑:Lettuce 版本 < 4.2)

Azure Redis SSL Cluster + Lettuce Java (EDIT: lettuce version < 4.2)

我需要使用 Azure Redis 集群,带密码,带 SSL,带流水线支持。

我一直在使用 Jedis,但它不支持集群+ssl+密码+流水线组合。

我尝试了生菜 (https://github.com/mp911de/lettuce/releases/tag/4.1.2.Final),但目前遇到了一个我无法自行解决的连接问题。

连接到 Azure Redis 集群 (2 * P4) 在没有 SSL 的情况下有效,但在有 SSL 的情况下无效。 我也可以使用 SSL 连接到单个节点,但不支持集群。 问题是当组合 cluster+ssl 时,auth 调用超时(命令通过线路发送但超时)。

没有 SSL 工作代码的集群如下所示:

RedisURI redisURI = RedisURI.Builder.redis(host, 6379)
  .withPassword(password)
  .build();
RedisClusterClient client = RedisClusterClient.create(redisURI);
RedisAdvancedClusterCommands<String, String> connection = client.connect().sync();
connection.set("a", "1");
System.out.println(connection.get("a"));

输出为1

启用 SSL:

RedisURI redisURI = RedisURI.Builder.redis(host, 6380)
  .withPassword(password)
  .withSsl(true)
  .build();
RedisClusterClient client = RedisClusterClient.create(redisURI);
RedisAdvancedClusterCommands<String, String> connection = client.connect().sync();
connection.set("a", "1");
System.out.println(connection.get("a"));

它在 1 分钟内挂起,log4j 日志如下所示:

2016-05-26 14:25:17,110 | TRACE | lettuce-nioEventLoop-3-1 | CommandEncoder | [/{CLIENT} -> {HOST}/{IP}:6380] Sent: *2

AUTH

{PASSWORD}
2016-05-26 14:26:17,134 | WARN  | main | ClusterTopologyRefresh | Cannot connect to RedisURI [host='***', port=6380]
com.lambdaworks.redis.RedisCommandTimeoutException: Command timed out
    at com.lambdaworks.redis.LettuceFutures.await(LettuceFutures.java:95)
    at com.lambdaworks.redis.LettuceFutures.awaitOrCancel(LettuceFutures.java:74)
    at com.lambdaworks.redis.AbstractRedisAsyncCommands.auth(AbstractRedisAsyncCommands.java:64)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connectToNode(RedisClusterClient.java:342)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connectToNode(RedisClusterClient.java:301)
    at com.lambdaworks.redis.cluster.ClusterTopologyRefresh.getConnections(ClusterTopologyRefresh.java:240)
    at com.lambdaworks.redis.cluster.ClusterTopologyRefresh.loadViews(ClusterTopologyRefresh.java:132)
    at com.lambdaworks.redis.cluster.RedisClusterClient.loadPartitions(RedisClusterClient.java:468)
    at com.lambdaworks.redis.cluster.RedisClusterClient.initializePartitions(RedisClusterClient.java:445)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connectClusterImpl(RedisClusterClient.java:359)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connect(RedisClusterClient.java:244)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connect(RedisClusterClient.java:231)
    at com.ubikod.ermin.reach.tools.Test.main(Test.java:20)
Exception in thread "main" com.lambdaworks.redis.RedisException: Cannot retrieve initial cluster partitions from initial URIs [RedisURI [host='***', port=6380]]
    at com.lambdaworks.redis.cluster.RedisClusterClient.loadPartitions(RedisClusterClient.java:471)
    at com.lambdaworks.redis.cluster.RedisClusterClient.initializePartitions(RedisClusterClient.java:445)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connectClusterImpl(RedisClusterClient.java:359)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connect(RedisClusterClient.java:244)
    at com.lambdaworks.redis.cluster.RedisClusterClient.connect(RedisClusterClient.java:231)
    at com.ubikod.ermin.reach.tools.Test.main(Test.java:20)

保持 SSL 和禁用集群有效:

RedisURI redisURI = RedisURI.Builder.redis(host, 6380)
  .withPassword(password)
  .withSsl(true)
  .build();
RedisClient client = RedisClient.create(redisURI);
RedisCommands<String, String> connection = client.connect().sync();
connection.set("a", "1");
System.out.println(connection.get("a"));

所以这不仅仅是一个 SSL 问题,它是一个 SSL + 集群组合问题。 我尝试使用 withStartTls、禁用对等验证、提高超时时间,这些都没有成功。

知道这是库错误还是 Azure Redis 错误吗?

我检查了 lettuce 的 wiki page,我注意到问题不是由库错误或 Azure Redis 错误引起的,不幸的是,只有 lettuce 不是支持带 SSL 的 Redis 集群,请参阅维基页面 Connecting to Redis using String RedisURI 小节中的以下内容。

lettuce supports SSL only on regular Redis connections. Master resolution using Redis Sentinel or Redis Cluster are not supported since both strategies provide Redis addresses to the native port. Redis Sentinel and Redis Cluster cannot provide the SSL ports.