美文网首页
docker redis 高可用哨兵+主从

docker redis 高可用哨兵+主从

作者: relax_小罗罗 | 来源:发表于2022-06-29 21:28 被阅读0次

    docker redis 高可用

    废话不多说,直接上yml文件

    version: "3.2"
    services:
    #服务名
      redis1:
    #镜像名称
        image: redis:6.0.9
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
            delay: 60s
          placement:
            constraints:
    #指定docker 节点
              - node.role == manager
    #开放端口
        ports:
          - "36379:6379"
    #追加命令
        command: redis-server --timeout 0 --tcp-keepalive 60 --bind 0.0.0.0 --slave-announce-ip 192.168.1.32 --slave-announce-port 36379 --requirepass password@123 --masterauth password@123 --masterauth password@123
    
      redis2:
        image: redis:6.0.9
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
            delay: 60s
          placement:
            constraints:
              - node.role == manager    
        ports:
          - "36380:6379"
        command: redis-server --timeout 0 --tcp-keepalive 60 --bind 0.0.0.0 --slave-announce-ip 192.168.1.32 --slave-announce-port 36380 --slaveof 192.168.1.32 36379 --requirepass password@123 --masterauth password@123
    
      redis3:
        image: redis:6.0.9
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
            delay: 60s
          placement:
            constraints:
              - node.role == manager    
        ports:
          - "36381:6379"
        command: redis-server --timeout 0 --tcp-keepalive 60 --bind 0.0.0.0 --slave-announce-ip 192.168.1.32 --slave-announce-port 36381 --slaveof 192.168.1.32 36379  --requirepass password@123 --masterauth password@123
        
    
      sentinel1:
        image: redis:6.0.9
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
          placement:
            constraints:
              - node.role == manager    
        ports:
          - "36479:26379"
        command: /bin/bash -c "touch /data/redis_sentinel.conf && redis-server /data/redis_sentinel.conf --sentinel monitor mysentinel 192.168.1.32 36379 2 --sentinel down-after-milliseconds mysentinel 5000 --sentinel parallel-syncs mysentinel 1 --sentinel failover-timeout mysentinel 180000 --sentinel announce-ip 192.168.1.32 --sentinel announce-port 36479 --sentinel auth-pass mysentinel password@123"
    
      sentinel2:
        image: redis:6.0.9
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
          placement:
            constraints:
              - node.role == manager                
        ports:
          - "36480:26379"
        command: /bin/bash -c "touch /data/redis_sentinel.conf && redis-server /data/redis_sentinel.conf --sentinel monitor mysentinel 192.168.1.32 36379 2 --sentinel down-after-milliseconds mysentinel 5000 --sentinel parallel-syncs mysentinel 1 --sentinel failover-timeout mysentinel 180000 --sentinel announce-ip 192.168.1.32 --sentinel announce-port 36480 --sentinel auth-pass mysentinel password@123"
    
      sentinel3:
        image: redis:6.0.9
        deploy:
          replicas: 1
          restart_policy:
            condition: on-failure
          placement:
            constraints:
              - node.role == manager                
        ports:
          - "36481:26379"
        command: /bin/bash -c "touch /data/redis_sentinel.conf && redis-server /data/redis_sentinel.conf --sentinel monitor mysentinel 192.168.1.32 36379 2 --sentinel down-after-milliseconds mysentinel 5000 --sentinel parallel-syncs mysentinel 1 --sentinel failover-timeout mysentinel 180000 --sentinel announce-ip 192.168.1.32 --sentinel announce-port 36481 --sentinel auth-pass mysentinel password@123"
    
    

    如果docker 不是集群模式 执行

    docker swarm init  
    docker stack deploy --compose-file=xxx.yml redis-sentinel
    

    命令详解

    --当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
    timeout 0 
    --保活检测,设置为0不检测,默认为300 
    tcp-keepalive 60 
    --绑定的主机地址
    bind 0.0.0.0 
    --解决docker 部署可能存在的:由于端口或IP映射导致的无法连接的问题
    slave-announce-ip 192.168.1.32
    slave-announce-port 36379
    -- 设置密码
    requirepass password@123 
    --当master服务设置了密码保护时,slav服务连接master的密码
    masterauth password@123 
    --设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
    slaveof 192.168.1.32 36379 
    --监控的IP 端口号 名称 sentinel通过投票后认为mater宕机的数量,此处为至少2个
    sentinel monitor mysentinel 192.168.1.32 36379 2
    
    --解决docker 部署可能存在的:由于端口或IP映射导致的无法连接的问题
    sentinel announce-ip 192.168.1.32
    sentinel announce-port 36481
    --如果redis有密码需要指定密码
    sentinel auth-pass mysentinel password@123
    --30秒ping不通主节点的信息,主观认为master宕机
    sentinel down-after-milliseconds mymaster 30000
    --故障转移后重新主从复制,1表示串行,>1并行
    sentinel parallel-syncs mymaster 1
    --故障转移开始,三分钟内没有完成,则认为转移失败
    sentinel failover-timeout mymaster 180000
    

    哨兵版

    java springboot配置,我这里使用的是1.x版本

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.Data;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.cache.CacheManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisSentinelConfiguration;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import redis.clients.jedis.JedisPoolConfig;
    
    import java.util.Set;
    
    /**
     * redis缓存集群哨兵模式配置
     *
     * @author luozy date 2019/7/9
     */
    @Data
    @Configuration
    @PropertySource(value = {"classpath:application-redis.properties"})
    @ConfigurationProperties(prefix = "spring.redis-dic")
    public class DictRedisSentinelConfig {
    
        //   @Autowired
        //  private RedisParam redisParam;
    
        private int dbIndex;
    
        private String password;
    
        private int timeout;
    
        private Long expire;
    
        private String sentinelMaster;
    
        private Set<String> sentinelNodes;
    
        private int maxIdle;
    
        private int minIdle;
    
        private int maxActive;
    
        private int maxWait;
    
        private boolean testOnBorrow;
    
    
        /**
         * 配置redis连接工厂
         *
         * @return
         */
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = false, havingValue = "true")
        public RedisConnectionFactory dictRedisConnectionFactory() {
    
            //哨兵配置
            RedisSentinelConfiguration configuration = new RedisSentinelConfiguration(sentinelMaster, sentinelNodes);
    
            JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration);
            jedisConnectionFactory.setDatabase(dbIndex);
            jedisConnectionFactory.setPassword(password);
            jedisConnectionFactory.setTimeout(timeout);
            jedisConnectionFactory.setPoolConfig(setPoolConfig(maxIdle, minIdle, maxActive, maxWait, testOnBorrow));
            return jedisConnectionFactory;
        }
    
        /**
         * 设置连接池属性
         *
         * @param maxIdle
         * @param minIdle
         * @param maxActive
         * @param maxWait
         * @param testOnBorrow
         * @return
         */
        public JedisPoolConfig setPoolConfig(int maxIdle, int minIdle, int maxActive, int maxWait, boolean testOnBorrow) {
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxIdle(maxIdle);
            poolConfig.setMinIdle(minIdle);
            poolConfig.setMaxTotal(maxActive);
            poolConfig.setMaxWaitMillis(maxWait);
            poolConfig.setTestOnBorrow(testOnBorrow);
            //  poolConfig.setTestOnReturn(true);
            return poolConfig;
        }
    
        /**
         * 配置redisTemplate 注入方式使用@Resource(name="dictRedisTemplate") 方式注入
         *
         * @return
         */
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = false, havingValue = "true")
        public RedisTemplate<String, Object> dictRedisTemplate() {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(dictRedisConnectionFactory());
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
                    Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            // 设置键(key)的序列化方式
            template.setKeySerializer(new StringRedisSerializer());
            // 设置值(value)的序列化方式
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = false, havingValue = "true")
        CacheManager dicCacheManager() {
            RedisCacheManager redisCacheManager = new RedisCacheManager(dictRedisTemplate());
            redisCacheManager.setUsePrefix(true);
            redisCacheManager.setDefaultExpiration(expire);
            return redisCacheManager;
        }
    
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = false, havingValue = "true")
        public RedisMessageListenerContainer redisMessageListenerContainer() {
    
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    
            container.setConnectionFactory(dictRedisConnectionFactory());
    
            return container;
    
        }
    
    }
    

    单节点版

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.Data;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.cache.CacheManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import redis.clients.jedis.JedisPoolConfig;
    
    /**
     * 枚举字典redis缓存单节点配置
     *
     * @author luozy
     * date 2019/7/9
     */
    @Data
    @Configuration
    @PropertySource(value = {"classpath:application-redis.properties"})
    @ConfigurationProperties(prefix = "spring.redis-dic")
    public class RedisConfig {
    
    
        private int dbIndex;
    
        private String host;
    
        private int port;
    
        private String password;
    
        private int timeout;
    
        private Long expire;
    
        private int maxIdle;
    
        private int minIdle;
    
        private int maxActive;
    
        private int maxWait;
    
        /**
         * 配置redis连接工厂
         *
         * @return
         */
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = true, havingValue = "false")
        public RedisConnectionFactory dictRedisConnectionFactory() {
            JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
            jedisConnectionFactory.setDatabase(dbIndex);
            jedisConnectionFactory.setHostName(host);
            jedisConnectionFactory.setPort(port);
            jedisConnectionFactory.setPassword(password);
            jedisConnectionFactory.setTimeout(timeout);
            jedisConnectionFactory.setPoolConfig(setPoolConfig(maxIdle, minIdle, maxActive, maxWait, true));
            return jedisConnectionFactory;
        }
    
    
        /**
         * 设置连接池属性
         *
         * @param maxIdle
         * @param minIdle
         * @param maxActive
         * @param maxWait
         * @param testOnBorrow
         * @return
         */
        public JedisPoolConfig setPoolConfig(int maxIdle, int minIdle, int maxActive, int maxWait, boolean testOnBorrow) {
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxIdle(maxIdle);
            poolConfig.setMinIdle(minIdle);
            poolConfig.setMaxTotal(maxActive);
            poolConfig.setMaxWaitMillis(maxWait);
            poolConfig.setTestOnBorrow(testOnBorrow);
            return poolConfig;
        }
    
        /**
         * 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
         *
         * @return
         */
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = true, havingValue = "false")
        public RedisTemplate<String, Object> dictRedisTemplate() {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(dictRedisConnectionFactory());
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            //设置键(key)的序列化方式
            template.setKeySerializer(new StringRedisSerializer());
            //设置值(value)的序列化方式
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = true, havingValue = "false")
        CacheManager dicCacheManager() {
            RedisCacheManager redisCacheManager = new RedisCacheManager(dictRedisTemplate());
            redisCacheManager.setUsePrefix(true);
            redisCacheManager.setDefaultExpiration(expire);
            return redisCacheManager;
        }
    
        @Bean
        @ConditionalOnProperty(name = "spring.redis-dic.sentinelMasterEnabled", matchIfMissing = true, havingValue = "false")
        public RedisMessageListenerContainer redisMessageListenerContainer() {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(dictRedisConnectionFactory());
            return container;
        }
    
    }
    

    配置文件

    #\u679A\u4E3E\u7F13\u5B58\u914D\u7F6E
    spring.cache.type=redis
    spring.redis-dic.host=15.22.68.89
    spring.redis-dic.port=6379
    #
    spring.redis-dic.sentinelMasterEnabled=false
    spring.redis-dic.sentinelMaster=mysentinel
    spring.redis-dic.sentinelNodes=15.22.68.89:36479,15.22.68.89:36480,15.22.68.89:36481
    spring.redis-dic.password=password@123
    spring.redis-dic.timeout=0
    spring.redis-dic.dbIndex=11
    spring.redis-dic.expire=300
    spring.redis-dic.maxIdle=-1
    spring.redis-dic.minIdle=-1
    spring.redis-dic.maxActive=100
    spring.redis-dic.maxWait=100
    spring.redis-dic.testOnBorrow=true
    spring.data.redis.repositories.enabled=false
    

    springboot cache+redis

    启动类增加
    @EnableCaching

     @Cacheable(value = "test", condition = "#id !=null", key = "#id", unless = "#result == null")
        public String test(String id) {
             System.out.println("。。。。");
            return deviceRepository.findByCode(code);
        }
    

    pom

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    

    相关文章

      网友评论

          本文标题:docker redis 高可用哨兵+主从

          本文链接:https://www.haomeiwen.com/subject/uvqxbrtx.html