一、lettuce
依赖:
<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;
}
二、jedis
依赖:
<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;
}
三、redisson
依赖:
<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