使用 RedisSentinelConfiguration 不会故障转移到下一个可用 sentinel/master
Using RedisSentinelConfiguration doesn't fail over to the next available sentinel/master
我正在尝试使用 redis-sentinel 为我的 redis 实例设置 HA。我假设我的 java 应用程序必须使用 RedisSentinelConfiguration 来创建连接工厂。因此我设置了如下所示的连接工厂
@Bean(name = "redisConnectionFactory")
public JedisConnectionFactory redisConnectionFactory() {
String redisHost = redisSystemProperties.getProperty("redis.host");
int redisPort = redisSystemProperties.getIntegerProperty("redis.port", DEFAULT_REDIS_PORT);
logger.info(format("Creating redis connection factory. host: %s, port: %d", redisHost, redisPort));
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(redisSentinelConfig(), jedisPoolConfig());
boolean usePool = Boolean.valueOf(redisSystemProperties.getProperty("pool.enabled", "true"));
connectionFactory.setUsePool(usePool);
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
@Bean(name ="redisSentinelConfig")
public RedisSentinelConfiguration redisSentinelConfig(){
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration();
for (int i = 0; i < MAX_REDIS_MASTER_NODES; i++) {
String hostPropertyName = format("redis.%d.host", i);
String host = redisSystemProperties().getProperty(hostPropertyName);
String portPropertyName = format("redis.%d.port", i);
String portStr = redisSystemProperties().getProperty(portPropertyName);
if (StrUtils.anyBlank(host, portStr)) {
break;
}
int port = toInt(portStr);
Assert.isTrue(port > 0, format("Invalid value '%s' for property '%s'", portStr, portPropertyName));
RedisNode redisNode = new RedisNode(host, port);
logger.info(format("Adding connection to redis sentinel [%d]: host: '%s', port: %d", i, host, port));
sentinelConfig.addSentinel(redisNode);
sentinelConfig.setMaster("mymaster");
}
return sentinelConfig;
}
创建RedisSentinelConfiguration的IP和端口号是我启动的sentinel实例。我已经为每个主人启动了一个哨兵。我有 3 个大师 运行,还有 3 个哨兵。只要映射到 sentinel 'mymaster' 的主节点是 运行,应用程序似乎就可以正常工作。一旦我关闭那个 redis 节点,应用程序就无法获得连接。我看到连接被拒绝错误。在调试时,我可以看到它正在尝试使用它在第一次尝试中使用的单个 Sentinel 配置来创建连接。
这是我的哨兵配置。
port 26379
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 1
sentinel failover-timeout mymaster 1
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
dir "/Users/skandula/redis-3.0.2"
sentinel leader-epoch mymaster 0
sentinel known-sentinel mymaster 127.0.0.1 26380 e4bc16a7435eec64512acc03404beb9799dea73e
sentinel known-sentinel mymaster 127.0.0.1 26381 493d598ce30dd4429bdc53c94cf297b8a0436c67
sentinel current-epoch 0
谁能告诉我我做错了什么?我正在使用 spring-data-redis 1.5.0.RELEASE 和 Jedis-2.7.0
谢谢
故障转移与实际实施之间存在差距,以挑选新选出的主节点。虽然 Sentinel 本身可能被配置为立即进行故障转移,但 java 驱动程序的实现可能会有点落后。您需要处理这些情况。
运行 sentinel example 您可以通过随机关闭 Redis and/or Sentinel 实例轻松探索行为,同时观察命令行打印出的错误以及恢复实际花费的时间。
您也可以使用 spring-retry to reschedule attempts of writing to redis. There's a ticket (DATAREDIS-370) open for integration RetryTemplate
- 所以您可能想投票给它。
我正在尝试使用 redis-sentinel 为我的 redis 实例设置 HA。我假设我的 java 应用程序必须使用 RedisSentinelConfiguration 来创建连接工厂。因此我设置了如下所示的连接工厂
@Bean(name = "redisConnectionFactory")
public JedisConnectionFactory redisConnectionFactory() {
String redisHost = redisSystemProperties.getProperty("redis.host");
int redisPort = redisSystemProperties.getIntegerProperty("redis.port", DEFAULT_REDIS_PORT);
logger.info(format("Creating redis connection factory. host: %s, port: %d", redisHost, redisPort));
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(redisSentinelConfig(), jedisPoolConfig());
boolean usePool = Boolean.valueOf(redisSystemProperties.getProperty("pool.enabled", "true"));
connectionFactory.setUsePool(usePool);
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
@Bean(name ="redisSentinelConfig")
public RedisSentinelConfiguration redisSentinelConfig(){
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration();
for (int i = 0; i < MAX_REDIS_MASTER_NODES; i++) {
String hostPropertyName = format("redis.%d.host", i);
String host = redisSystemProperties().getProperty(hostPropertyName);
String portPropertyName = format("redis.%d.port", i);
String portStr = redisSystemProperties().getProperty(portPropertyName);
if (StrUtils.anyBlank(host, portStr)) {
break;
}
int port = toInt(portStr);
Assert.isTrue(port > 0, format("Invalid value '%s' for property '%s'", portStr, portPropertyName));
RedisNode redisNode = new RedisNode(host, port);
logger.info(format("Adding connection to redis sentinel [%d]: host: '%s', port: %d", i, host, port));
sentinelConfig.addSentinel(redisNode);
sentinelConfig.setMaster("mymaster");
}
return sentinelConfig;
}
创建RedisSentinelConfiguration的IP和端口号是我启动的sentinel实例。我已经为每个主人启动了一个哨兵。我有 3 个大师 运行,还有 3 个哨兵。只要映射到 sentinel 'mymaster' 的主节点是 运行,应用程序似乎就可以正常工作。一旦我关闭那个 redis 节点,应用程序就无法获得连接。我看到连接被拒绝错误。在调试时,我可以看到它正在尝试使用它在第一次尝试中使用的单个 Sentinel 配置来创建连接。
这是我的哨兵配置。
port 26379
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 1
sentinel failover-timeout mymaster 1
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
dir "/Users/skandula/redis-3.0.2"
sentinel leader-epoch mymaster 0
sentinel known-sentinel mymaster 127.0.0.1 26380 e4bc16a7435eec64512acc03404beb9799dea73e
sentinel known-sentinel mymaster 127.0.0.1 26381 493d598ce30dd4429bdc53c94cf297b8a0436c67
sentinel current-epoch 0
谁能告诉我我做错了什么?我正在使用 spring-data-redis 1.5.0.RELEASE 和 Jedis-2.7.0
谢谢
故障转移与实际实施之间存在差距,以挑选新选出的主节点。虽然 Sentinel 本身可能被配置为立即进行故障转移,但 java 驱动程序的实现可能会有点落后。您需要处理这些情况。
运行 sentinel example 您可以通过随机关闭 Redis and/or Sentinel 实例轻松探索行为,同时观察命令行打印出的错误以及恢复实际花费的时间。
您也可以使用 spring-retry to reschedule attempts of writing to redis. There's a ticket (DATAREDIS-370) open for integration RetryTemplate
- 所以您可能想投票给它。