Как настроить экземпляр Redis в Cloudfoundry в подчиненном режиме?

Я пытаюсь настроить репликацию master/slave в Cloudfoundry, но всегда вылетаю с ошибкой «ERR unknown command SLAVEOF». Я использую Jedis в качестве базового клиента spring-data-reids с этим кодом:

@Configuration
@ComponentScan(basePackages = { Constants.REDIS_PACKAGE })
@Order(1)
public class KeyValueConfig {

    @Inject
    @Named("redisMasterConnectionFactory")
    private RedisConnectionFactory redisMasterConnectionFactory;

    @Inject
    @Named("redisSlaveConnectionFactory")
    private RedisConnectionFactory redisSlaveConnectionFactory;

    @Inject
    @Named("redisCacheConnectionFactory")
    private RedisConnectionFactory redisCacheConnectionFactory;

    @Bean
    public StringRedisTemplate redisMasterTemplate() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(
                redisMasterConnectionFactory);
        HealthChecks.register(new RedisHealthCheck(stringRedisTemplate,
                "master"));
        return stringRedisTemplate;
    }

    @Bean
    public StringRedisTemplate redisSlaveTemplate() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(
                redisSlaveConnectionFactory);
        HealthChecks
                .register(new RedisHealthCheck(stringRedisTemplate, "slave"));
        return stringRedisTemplate;
    }

    @Bean
    public StringRedisTemplate redisCacheTemplate() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(
                redisCacheConnectionFactory);
        HealthChecks
                .register(new RedisHealthCheck(stringRedisTemplate, "cache"));
        return stringRedisTemplate;
    }

    /**
     * Properties to support the local and test mode of operation.
     */
    @Configuration
    @Profile({ Profiles.LOCAL, Profiles.PROD, Profiles.TEST })
    static class Default implements MasterSlaveConfig {

        @Inject
        private Environment environment;

        @Bean
        public RedisConnectionFactory redisMasterConnectionFactory() {
            JedisConnectionFactory redis = new JedisConnectionFactory();
            redis.setHostName(environment.getProperty("redis.master.hostname"));
            redis.setPort(environment.getProperty("redis.master.port",
                    Integer.class));
            redis.setPassword(environment.getProperty("redis.master.password"));
            redis.setUsePool(true);
            return redis;
        }

        @Bean
        public RedisConnectionFactory redisSlaveConnectionFactory() {
            JedisConnectionFactory redis = new JedisConnectionFactory();
            redis.setHostName(environment.getProperty("redis.slave.hostname"));
            redis.setPort(environment.getProperty("redis.slave.port",
                    Integer.class));
            redis.setPassword(environment.getProperty("redis.slave.password"));
            redis.setUsePool(true);
            return redis;
        }

        @Bean
        public RedisConnectionFactory redisCacheConnectionFactory()
                throws Exception {
            JedisConnectionFactory redis = new JedisConnectionFactory();
            redis.setHostName(environment.getProperty("redis.cache.hostname"));
            redis.setPort(environment.getProperty("redis.cache.port",
                    Integer.class));
            redis.setPassword(environment.getProperty("redis.cache.password"));
            redis.setUsePool(true);
            return redis;
        }
    }

    /**
     * Properties to support the cloud mode of operation.
     */
    @Configuration
    @Profile(Profiles.CLOUDFOUNDRY)
    static class Cloud implements MasterSlaveConfig {

        @Bean
        public RedisConnectionFactory redisMasterConnectionFactory()
                throws Exception {
            CloudPoolConfiguration cloudPoolConfiguration = new CloudPoolConfiguration();
            cloudPoolConfiguration.setPoolSize("3-5");

            CloudRedisConnectionFactoryBean factory = new CloudRedisConnectionFactoryBean();
            factory.setCloudPoolConfiguration(cloudPoolConfiguration);
            factory.setServiceName("redis-master");
            factory.afterPropertiesSet();

            return factory.getObject();
        }

        @Bean
        public RedisConnectionFactory redisSlaveConnectionFactory()
                throws Exception {
            CloudPoolConfiguration cloudPoolConfiguration = new CloudPoolConfiguration();
            cloudPoolConfiguration.setPoolSize("3-5");

            CloudRedisConnectionFactoryBean factory = new CloudRedisConnectionFactoryBean();
            factory.setCloudPoolConfiguration(cloudPoolConfiguration);
            factory.setServiceName("redis-slave");
            factory.afterPropertiesSet();

            RedisConnectionFactory redisSlaveConnectionFactory = initSlaveOnMaster(factory);

            return redisSlaveConnectionFactory;
        }

        private RedisConnectionFactory initSlaveOnMaster(
                CloudRedisConnectionFactoryBean factory) throws Exception {
            RedisConnectionFactory redisSlaveConnectionFactory = factory
                    .getObject();

            RedisServiceInfo serviceInfo = new CloudEnvironment()
                    .getServiceInfo("redis-master", RedisServiceInfo.class);

            Jedis jedis = (Jedis) redisSlaveConnectionFactory.getConnection()
                    .getNativeConnection();
            jedis.slaveof(serviceInfo.getHost(), serviceInfo.getPort());
            return redisSlaveConnectionFactory;
        }

        @Bean
        public RedisConnectionFactory redisCacheConnectionFactory()
                throws Exception {
            CloudPoolConfiguration cloudPoolConfiguration = new CloudPoolConfiguration();
            cloudPoolConfiguration.setPoolSize("3-5");

            CloudRedisConnectionFactoryBean factory = new CloudRedisConnectionFactoryBean();
            factory.setCloudPoolConfiguration(cloudPoolConfiguration);
            factory.setServiceName("redis-cache");
            factory.afterPropertiesSet();

            return factory.getObject();
        }
    }

    interface MasterSlaveConfig {

        RedisConnectionFactory redisMasterConnectionFactory() throws Exception;

        RedisConnectionFactory redisSlaveConnectionFactory() throws Exception;

        RedisConnectionFactory redisCacheConnectionFactory() throws Exception;
    }

}

person Vincent Devillers    schedule 23.11.2012    source источник


Ответы (1)


Хорошо... После проверки кода я нашел это:

команда переименования SLAVEOF "" в redis.conf.erb (https://github.com/cloudfoundry/vcap-services/blob/master/redis/resources/redis.conf.erb)

Итак, команда SLAVEOF отключена на Cloudfoudry, и так:

  • МОНИТОР
  • BGSСОХРАНИТЬ
  • BGREWRITEAOF
  • РАБ
  • ОТЛАЖИВАТЬ
  • СИНХРОНИЗАЦИЯ
person Vincent Devillers    schedule 23.11.2012