依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </dependency>
配置:
spring: redis: database: 0 sentinel: master: "mymaster" lettuce: pool: max-active: 8 #连接池最大连接数(使用负值表示没有限制) max-wait: -1 #连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 8 #连接池中的最大空闲连接 min-idle: 0 #连接池中的最小空闲连接 timeout: 30000 #连接超时时间(毫秒)
连接服务:
@Autowired RedisProperties redisProperties; @Value("${redis.sentinel}") private String redisSentinel; // 读取pool配置信息 @Bean public GenericObjectPoolConfig<Object> genericObjectPoolConfig() { RedisProperties.Pool pool = redisProperties.getLettuce().getPool(); GenericObjectPoolConfig<Object> genericObjectPoolConfig = new GenericObjectPoolConfig<>(); genericObjectPoolConfig.setMaxIdle(pool.getMaxIdle()); genericObjectPoolConfig.setMinIdle(pool.getMinIdle()); genericObjectPoolConfig.setMaxTotal(pool.getMaxActive()); genericObjectPoolConfig.setMaxWaitMillis(pool.getMaxWait().toMillis()); return genericObjectPoolConfig; } // 将哨兵放到配置中 @Bean public RedisSentinelConfiguration redisSentinelConfiguration() throws Exception { RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(); redisSentinelConfiguration.setMaster(redisProperties.getSentinel().getMaster()); try { ArrayList<RedisNode> redisNodeList = new ArrayList<>(); // redis://10.2.33.8:10013,redis://10.2.33.9:10013,redis://10.2.33.10:10013 String[] redisSentinels = redisSentinel.split(","); for (String sentinelConfig : redisSentinels) { String sentinelValue = sentinelConfig.substring(sentinelConfig.indexOf("//") + 2); String[] sentinel = sentinelValue.split(":"); redisNodeList.add(new RedisNode(sentinel[0], Integer.parseInt(sentinel[1]))); } redisSentinelConfiguration.setSentinels(redisNodeList); } catch (Exception e) { throw new Exception("读取解析redis的sentinel配置错误"); } return redisSentinelConfiguration; } @Bean public LettuceConnectionFactory lettuceConnectionFactory( GenericObjectPoolConfig<Object> genericObjectPoolConfig, RedisSentinelConfiguration redisSentinelConfiguration) { LettuceClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration .builder().poolConfig(genericObjectPoolConfig).build(); return new LettuceConnectionFactory(redisSentinelConfiguration, lettucePoolingClientConfiguration); } @Bean public RedisTemplate<String, Object> redisTemplate( LettuceConnectionFactory lettuceConnectionFactory) { // 创建RedisTemplate<String, Object>对象 RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // 配置连接工厂 redisTemplate.setConnectionFactory(lettuceConnectionFactory); // 定义Jackson2JsonRedisSerializer序列化对象 Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>( Object.class); ObjectMapper objectMapper = new ObjectMapper(); // 指定要序列化的域, filed,get和set,以及修饰符范围, ANY是都有包括private和public objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化要输入的类型, 类必须是非final修饰的, final修饰的类, 比如Stirng、Integer等会报异常 objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); jsonRedisSerializer.setObjectMapper(objectMapper); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // redis key序列化方式使用stringRedisSerializer redisTemplate.setKeySerializer(stringRedisSerializer); // redis value序列化方式使用jsonRedisSerializer redisTemplate.setValueSerializer(jsonRedisSerializer); // redis hash key序列化方式使用stringRedisSerializer redisTemplate.setHashKeySerializer(stringRedisSerializer); // redis hash value序列化方式使用jsonRedisSerializer redisTemplate.setHashValueSerializer(jsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.15.4</version> </dependency>
配置:
spring: redis: database: 0 jedis: pool: max-active: 8 #连接池最大连接数(使用负值表示没有限制) max-wait: -1 #连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 8 #连接池中的最大空闲连接 min-idle: 0 #连接池中的最小空闲连接 timeout: 30000 #连接超时时间(毫秒)
连接服务:
@Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { // 创建RedisTemplate<String, Object>对象 RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // 配置连接工厂 redisTemplate.setConnectionFactory(factory); // 定义Jackson2JsonRedisSerializer序列化对象 Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>( Object.class); ObjectMapper objectMapper = new ObjectMapper(); // 指定要序列化的域, filed,get和set,以及修饰符范围, ANY是都有包括private和public objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化要输入的类型, 类必须是非final修饰的, final修饰的类, 比如Stirng、Integer等会报异常 objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); jsonRedisSerializer.setObjectMapper(objectMapper); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // redis key序列化方式使用stringRedisSerializer redisTemplate.setKeySerializer(stringRedisSerializer); // redis value序列化方式使用jsonRedisSerializer redisTemplate.setValueSerializer(jsonRedisSerializer); // redis hash key序列化方式使用stringRedisSerializer redisTemplate.setHashKeySerializer(stringRedisSerializer); // redis hash value序列化方式使用jsonRedisSerializer redisTemplate.setHashValueSerializer(jsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
依赖:
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>${redisson.version}</version> </dependency>
配置:(redisson.yml)
sentinelServersConfig: #如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。 idleConnectionTimeout: 10000 #pingTimeout: 1000 #同任何节点建立连接时的等待超时。时间单位是毫秒。 connectTimeout: 10000 #等待节点回复命令的时间。该时间从命令发送成功时开始计时。 timeout: 3000 #如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。 retryAttempts: 3 #在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。 retryInterval: 1500 #当与某个节点的连接断开时,等待与其重新建立连接的时间间隔。时间单位是毫秒。 #reconnectionTimeout: 3000 #在某个节点执行相同或不同命令时,连续 失败 failedAttempts(执行失败最大次数) 时,该节点将被从可用节点列表里清除,直到 reconnectionTimeout(重新连接时间间隔) 超时以后再次尝试。 #failedAttempts: 3 #password: null #每个连接的最大订阅数量。 subscriptionsPerConnection: 5 #在Redis节点里显示的客户端名称 clientName: null #WeightedRoundRobinBalancer - 权重轮询调度算法;RoundRobinLoadBalancer - 轮询调度算法;RandomLoadBalancer - 随机调度算法 loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {} #从节点发布和订阅连接的最小空闲连接数 #slaveSubscriptionConnectionMinimumIdleSize: 1 #从节点发布和订阅连接池大小 #slaveSubscriptionConnectionPoolSize: 50 #从节点,每个 从服务节点里用于普通操作(非发布和订阅)的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时读取反映速度。 slaveConnectionMinimumIdleSize: 32 #从节点,每个 从服务节点里用于普通操作(非 发布和订阅)连接的连接池最大容量。连接池的连接数量自动弹性伸缩。 slaveConnectionPoolSize: 64 #多从节点的环境里,每个 主节点的最小保持连接数(长连接)。长期保持一定数量的连接有利于提高瞬时写入反应速度。 masterConnectionMinimumIdleSize: 32 #主节点的连接池最大容量。连接池的连接数量自动弹性伸缩。 masterConnectionPoolSize: 64 #设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。 MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取。 readMode: "SLAVE" #哨兵地址 #sentinelAddresses: #- "redis://127.0.0.1:26379" #- "redis://127.0.0.1:26389" #主服务器的名称是哨兵进程中用来监测主从服务切换情况的。 masterName: "mymaster" database: 0 #这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。 threads: 0 #这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。 nettyThreads: 0 #Redisson的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在Redis里的读取和存储。 codec: !<org.redisson.codec.JsonJacksonCodec> {} #TransportMode.NIO;TransportMode.EPOLL(Linux);TransportMode.KQUEUE(macOS) "transportMode": "NIO"
连接服务:
@Value("${redis.sentinel}") private String redisSentinel; @Autowired RedisProperties redisProperties; @Bean RedissonClient redissonClient() throws IOException { ResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource("redisson.yml"); Config config = Config.fromYAML(resource.getInputStream()); SentinelServersConfig sentinelServersConfig = config.useSentinelServers(); String[] redisSentinels = redisSentinel.split(","); for (String sentinelConfig : redisSentinels) { sentinelServersConfig.addSentinelAddress(sentinelConfig); } //设置json序列化方式 config.setCodec(new JsonJacksonCodec()); return Redisson.create(config); }
1、搭建服务器
注册server到服务中:
D:\install\redis\redis-6379> redis-server --service-install redis.windows.conf --service-name redis-6379
启动服务:
redis-server.exe --service-start --service-name redis-6379
2、搭建哨兵
注册sentinel到服务中:
D:\install\redis\redis-6379>redis-server.exe --service-install redis.sentinel.conf --sentinel --service-name redis-sentinel-6379
启动服务:
redis-server.exe --service-start --service-name redis-sentinel-6379
3、批量启动
@echo off redis-server.exe --service-start --service-name redis_6379 redis-server.exe --service-start --service-name redis_6380 redis-server.exe --service-start --service-name redis_6381 redis-server.exe --service-start --service-name redis-sentinel-6379 redis-server.exe --service-start --service-name redis-sentinel-6380 redis-server.exe --service-start --service-name redis-sentinel-6381 exit
4、批量停止
@echo off redis-server.exe --service-stop --service-name redis-sentinel-6379 redis-server.exe --service-stop --service-name redis-sentinel-6380 redis-server.exe --service-stop --service-name redis-sentinel-6381 redis-server.exe --service-stop --service-name redis_6381 redis-server.exe --service-stop --service-name redis_6380 redis-server.exe --service-stop --service-name redis_6379 exit