引言
前两天在写一个实时数据处理的项目,项目要求是 1s 要处理掉 1k 的数据,这时候显然光靠查数据库是不行的,技术选型的时候老大跟我提了一下使用 Layering-Cache 这个开源项目来做缓存框架。
之间问了一下身边的小伙伴,似乎对这块了解不多。一般也就用用 Redis 来缓存,应该是很少用多级缓存框架来专门性的管理缓存吧。
趁着这个机会,我多了解了一些关于 SpringBoot 中缓存的相关技术,于是有了这篇文章!
在项目性能需求比较高时,就不能单单依赖数据库访问来获取数据了,必须引入缓存技术。
常用的有本地缓存、Redis 缓存。
- 本地缓存:也就是内存,速度快,缺点是不能持久化,一旦项目关闭,数据就会丢失。而且不能满足分布式系统的应用场景(比如数据不一致的问题)。
- Redis 缓存:也就是利用数据库等,最常见的就是 Redis。Redis 的访问速度同样很快,可以设置过期时间、设置持久化方法。缺点是会受到网络和并发访问的影响。
本节介绍三种缓存技术:Spring Cache、Layering Cache 框架、Alibaba JetCache 框架。示例使用的 SpringBoot 版本是 2.1.3.RELEASE。非 SpringBoot 项目请参考文章中给出的文档地址。
项目源码地址:https://github.com/laolunsi/spring-boot-examples
一、Spring Cache
Spring Cache 是 Spring 自带的缓存方案,使用简单,既可以使用本地缓存,也可以使用 Redis
CacheType 包括:
GENERIC, JCACHE, EHCACHE, HAZELCAST, INFINISPAN, COUCHBASE, REDIS, CAF本文来源gaodai#ma#com搞@@代~&码网FEINE, SIMPLE, NONE
Spring Cache 的使用很简单,引入 即可,我这里使用创建的是一个 web 项目,引入的 `spring-boot-starter-web` 包含了 。
这里利用 Redis 做缓存,再引入 spring-boot-starter-data-redis
依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--Redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在配置类 or Application 类上添加 @EnableCaching 注解以启动缓存功能。
配置文件很简洁(功能也比较少):
server: port: 8081 servlet: context-path: /api spring: cache: type: redis redis: host: 127.0.0.1 port: 6379 database: 1
下面我们编写一个对 User 进行增删改查的 Controller,实现对 User 的 save/delete/findAll 三个操作。为演示方便,DAO 层不接入数据库,而是使用 HashMap 来直接模拟数据库操作。
我们直接看 service 层的接口实现:
@Service public class UserServiceImpl implements UserService { @Autowired private UserDAO userDAO; @Override @Cacheable(value = "user", key = "#userId") public User findById(Integer userId) { return userDAO.findById(userId); } @Override @CachePut(value = "user", key = "#user.id", condition = "#user.id != null") public User save(User user) { user.setUpdateTime(new Date()); userDAO.save(user); return userDAO.findById(user.getId()); } @Override @CacheEvict(value = "user", key = "#userId") public boolean deleteById(Integer userId) { return userDAO.deleteById(userId); } @Override public List<User> findAll() { return userDAO.findAll(); } }