Redis 是目前业界使用最广泛的内存数据存储。相比 Memcached,Redis 支持更丰富的数据结构,例如 hashes, lists, sets ,sortedsets等。数据库有分库分表,当然redis也能实现mysql一样的分库逻辑。本文介绍 Redis 在 Spring Boot 中分库的应用场景。
1、引入依赖包
<!-- 引入 redis 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 引入 Lettuce池 依赖 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- 引入 fastjson 依赖,序列化使用的是fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.44</version> </dependency>
SpringBoot 提供了对 Redis 集成的组件包:spring-boot-starter-data-redis,spring-boot-starter-data-redis依赖于spring-data-redis 和 lettuce 。lettuce使用netty NIO来管理连接对象的,十分高效且线程安全,多个线程可共享一个connection对象。
SpringBoot2.0升级了redis池,从jedis升级到了lettuce,而且用户可无感知的切换到lettuce。
2.添加配置文件
两种添加配置文件的方式,一种是application.properties,另一种是application.yml。读者选择一种即可。
application.properties
#redis db1 spring.redis.redis-onedb.database=1 spring.redis.redis-onedb.hostName=localhost spring.redis.redis-onedb.port=6379 spring.redis.redis-onedb.timeout=5000 #redis db2 spring.redis.redis-twodb.database=2 spring.redis.redis-twodb.hostName=localhost spring.redis.redis-twodb.port=6379 spring.redis.redis-twodb.timeout=5000 spring.redis.lettuce.pool.MaxTotal=50 spring.redis.lettuce.pool.minIdle=1 spring.redis.lettuce.pool.maxWaitMillis=5000 spring.redis.lettuce.pool.maxIdle=5 spring.redis.lettuce.pool.testOnBorrow=true spring.redis.lettuce.pool.testOnReturn=true spring.redis.lettuce.pool.testWhileIdle=true
application.yml
spring: redis: lettuce: pool: MaxTotal: 50 minIdle: 1 maxWaitMillis: 5000 maxIdle: 5 testOnBorrow: true testOnReturn: true testWhileIdle: true redis-twodb: database: 1 hostName: localhost port: 6379 timeout: 5000 redis-onedb: database: 2 hostName: localhost port: 6379 timeout: 5000
3.配置类RedisConfig
@Configuration public class RedisConfig { @Bean @ConfigurationProperties(prefix = "spring.redis.lettuce.pool") @Scope(value = "prototype") public GenericObjectPoolConfig redisPool(){ return new GenericObjectPoolConfig(); } @Bean @ConfigurationProperties(prefix = "spring.redis.redis-onedb") public RedisStandaloneConfiguration redisConfigA(){ return new RedisStandaloneConfiguration(); } @Primary @Bean public LettuceConnectionFactory factoryA(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfigA){ LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder() .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build(); return new LettuceConnectionFactory(redisConfigA, clientConfiguration); } @Bean(name = "oneRedis") public StringRedisTemplate redisBusTemplate(@Qualifier("factoryA") LettuceConnectionFactory factoryA){ StringRedisTemplate template = getRedisTemplate(); template.setConnectionFactory(factoryA); return template; } @Bean @ConfigurationProperties(prefix = "spring.redis.redis-twodb") public RedisStandaloneConfiguration redisConfigB(){ return new RedisStandaloneConfiguration(); } @Bean public LettuceConnectionFactory factoryB(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfigB){ LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder() .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build(); return new LettuceConnectionFactory(redisConfigB, clientConfiguration); } @Bean(name = "twoRedis") public StringRedisTemplate redisLoginTemplate(@Qualifier("factoryB")LettuceConnectionFactory factoryB){ StringRedisTemplate template = getRedisTemplate(); template.setConnectionFactory(factoryB); return template; } private StringRedisTemplate getRedisTemplate(){ StringRedisTemplate template = new StringRedisTemplate(); template.setValueSerializer(new GenericFastJsonRedisSerializer()); template.setValueSerializer(new StringRedisSerializer()); return template; } }
RedisConfig类中配置的Lettuce多例模式池对象。
@Bean @ConfigurationProperties(prefix = "spring.redis.lettuce.pool") @Scope(value = "prototype") public GenericObjectPoolConfig redisPool(){ return new GenericObjectPoolConfig(); }
我们来梳理一下:
-
RedisTemplate对象 依赖 LettuceConnectionFactory对象;
-
LettuceConnectionFactory对象 依赖 RedisStandaloneConfiguration池配置对象以及Redis配置对象。
-
oneRedis->factoryA->redisConfigA + redisPool , twoRedis->factoryB->redisConfigB + redisPool
编写测试代码RedisTestor类的run方法。
System.out.println("在db1中设置key的值为:hello db1"); oneRedis.opsForValue().set("key", "hello db1"); System.out.println("在db2中设置key的值为:hello db1"); twoRedis.opsForValue().set("key", "hello db1"); System.out.println("db1中key:"+oneRedis.opsForValue().get("key")); System.out.println("db2中key:"+twoRedis.opsForValue().get("key"));
查看db1、db2的数据
完整的demo项目,请关注公众号“前沿科技bot“并发送"状态机"获取。
查看更多 “Java架构师方案” 系列文章 以及 SpringBoot2.0学习示例