Redis介绍
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
如何使用
1. 引入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
Spring Boot 提供了对 Redis 集成的组件包:spring-boot-starter-data-redis
,spring-boot-starter-data-redis
依赖于spring-data-redis
和 lettuce
。Spring Boot 1.0 默认使用的是 Jedis 客户端,2.0 替换成 Lettuce,但如果你从 Spring Boot 1.5.X 切换过来,几乎感受不大差异,这是因为 spring-boot-starter-data-redis
为我们隔离了其中的差异性。
Lettuce 是一个可伸缩线程安全的 Redis 客户端,多个线程可以共享同一个 RedisConnection,它利用优秀 netty NIO 框架来高效地管理多个连接。
2. 在application.properties添加相关配置文件
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=100
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=5000
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=50
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=20
3. 以上两歩就已经配置好了Redis. 好了,接下来就可以直接使用了
@RestController
public class TestRedisController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@RequestMapping(value = "redis")
public String redis(String phone) {
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
String name = opsForValue.get(phone);
return name;
}
}
加入缓存
1. 在spring boot 的启动类上加上@EnableCaching注解,开启缓存。
@EnableCaching
@SpringBootApplication
public class ReycoApplication {
public static void main(String[] args) {
SpringApplication.run(ReycoApplication.class, args);
}
}
或者编辑一个配置类,开启缓存,及key的生成器
/**
* 缓存配置类
*
* @author reyco
*
*/
@Configuration
@EnableCaching
public class CacheConfig {
/**
* 缓存key的生成器
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}
2. 在Service层方法上加上@Cacheable注解:使用缓存
被缓存对象必须实现Serializable接口:
public class User implements Serializable{
private Integer id;
private String name;
private String password;
getter...setter...
}
@Service("userService")
public class UserService{
@Cacheable(value="user-key")
public User get(Integer id){
return userDao.get(id);
}
}
3. 测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes=ReycoApplication.class)
public class ReycoApplicationTests {
@Autowired
private UserService userService;
@Test
public void get() {
User user = userService.get(1);
System.out.println(user);
user = userService.get(1);
System.out.println(user);
}
}
效果
2019-10-19 21:32:31.760 WARN 2672 --- [ main] com.zaxxer.hikari.util.DriverDataSource : Registered driver with driverClassName=com.mysql.jdbc.Driver was not found, trying direct instantiation.
2019-10-19 21:32:34.131 INFO 2672 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-10-19 21:32:34.623 DEBUG 2672 --- [ main] com.reyco.core.dao.UserDao.get : ==> Preparing: select * from user where id = ?
2019-10-19 21:32:34.641 DEBUG 2672 --- [ main] com.reyco.core.dao.UserDao.get : ==> Parameters: 4(Integer)
2019-10-19 21:32:34.695 DEBUG 2672 --- [ main] com.reyco.core.dao.UserDao.get : <== Total: 1
User [id=4, name=喜剧1, password=123456]
User [id=4, name=喜剧1, password=123456]
2019-10-19 21:32:34.854 DEBUG 2672 --- [ Thread-4] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@76b1e9b8, started on Sat Oct 19 21:32:29 CST 2019
2019-10-19 21:32:34.857 INFO 2672 --- [ Thread-4] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2019-10-19 21:32:35.105 INFO 2672 --- [ Thread-4] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2019-10-19 21:32:35.107 INFO 2672 --- [ Thread-4] o.s.s.c.ThreadPoolTaskScheduler : Shutting down ExecutorService 'threadPoolTaskScheduler'
4.常用缓存注解
@CacheConfig
这个注解的的主要作用就是全局配置缓存,比如配置缓存的名字(cacheNames),只需要在类上配置一次,下面的方法就默认以全局配置为主,不需要二次配置,节省了部分代码。
@Cacheable
这个注解是最重要的,主要实现的功能再进行一个读操作的时候。就是先从缓存中查询,如果查找不到,就会走数据库的执行方法,这是缓存的注解最重要的一个方法,基本上我们的所有缓存实现都要依赖于它。它具有的属性为cacheNames:缓存名字,condtion:缓存的条件,unless:不缓存的条件。可以指定SPEL表达式来实现,也可以指定缓存的key,缓存的内部实现一般都是key,value形式,类似于一个Map(实际上cacheable的缓存的底层实现就是concurrenHashMap),指定了key,那么缓存就会以key作为键,以方法的返回结果作为值进行映射。
@CacheEvict
这个注解主要是配合@Cacheable一起使用的,它的主要作用就是清除缓存,当方法进行一些更新、删除操作的时候,这个时候就要删除缓存。如果不删除缓存,就会出现读取不到最新缓存的情况,拿到的数据都是过期的。它可以指定缓存的key和conditon,它有一个重要的属性叫做allEntries默认是false,也可以指定为true,主要作用就是清除所有的缓存,而不以指定的key为主。
@CachePut
这个注解它总是会把数据缓存,而不会去每次做检查它是否存在,相比之下它的使用场景就比较少,毕竟我们希望并不是每次都把所有的数据都给查出来,我们还是希望能找到缓存的数据,直接返回,这样能提升我们的软件效率。
@cache
这个注解它是上面的注解的综合体,包含上面的三个注解(cacheable、cachePut、CacheEvict),可以使用这一个注解来包含上面的所有的注解.