8-27 kv缓存初步学习
举个简单的例子,我们可以类比去图书馆看书。
没有使用缓存的情况
当我们想要查看某本书的时候(查看数据库的记录),需要先去图书馆找到这本书所在的类目(记录存在的表),然后再找到这本书,看一会后再把这本书还回去。
但是如果有几本我们常看的数,我们每次看都要去图书馆取,取完了再放回去太麻烦。
使用缓存的情况
当我们想要查看某本书的时候(查看数据库的记录),需要先去图书馆找到这本书所在的类目(记录存在的表),然后再找到这本书,把这本书借回去放到自己的书架上。
这样做我们可以对一些我们频繁阅读的书籍放在触手可及的书架上,大大节约了时间成本。
总结:redis缓存是一种key-value缓存数据库,是对数据库频繁访问的某些热点字段的一种优化方案。
kv是把热点数据作为Key-Value形式存储的一种
<dependency>
<groupId>org.redissongroupId>
<artifactId>redissonartifactId>
<version>2.5.1version>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>2.9.0version>
dependency>
kv缓存框架采用的是工厂设计模式创建指定存储的kvCacheWrapper
当然,这些CacheWrapper我们需要随着spring的启动而被创建(就像Repository一样),因此我们需要指定在springbean初始化的时候对其进行创建。@PostConstruct注解下的方法可以在spring加载这个类的时候自动调用。
首先,我们通过依赖注入的方式引入KvCacheFactory。
@Autowired
private KvCacheFactory kvCacheFactory;
接着,在初始化方法下通过kvCacheFactory.create()创建特定的kvCacheWrapper接口
在创建之前,先来了解一下KvCacheFactory.created()所需的参数
比如说我们这里创建一个User的缓存接口。
@PostConstruct
public void init()
{
userCache = kvCacheFactory.create(new CacheOptions("user", 1, DateUtils.SECOND_PER_DAY),
new RepositoryProvider<Long, User>() {
@Override
public User findByKey(Long key) throws Exception
{
return repository.findById(key).orElse(null);
}
@Override
public Map<Long, User> findByKeys(java.util.Collection<Long> keys) throws Exception
{
return repository.findByIdIn(keys).stream().collect(Collectors.toMap(User::getId, t -> t));
}
}, new BeanModelConverter<>(User.class));
}
通过查看KvCache接口我们可以查看它的所有用法
public interface KvCache<K, T>
{
// 只从缓存中查找,如果缓存中没有,则返回null(不进入数据库)。
T findByKey(K key, boolean cacheOnly);
// 先从缓存中查找,如果缓存中没有进入数据库中查找,找到后缓存到redis中。
T findByKey(K key);
// 同上
Map<K, T> findByKeys(Collection<K> keys, boolean cacheOnly) throws KvCacheException;
// 同上
Map<K, T> findByKeys(Collection<K> keys) throws KvCacheException;
// 保存到缓存中
void save(K key, T value) throws KvCacheException;
// 批量保存
void saveMany(Map<K, T> items) throws KvCacheException;
// 刷新缓存(重新加载内容,写入缓存并返回)
T refresh(K key) throws Exception;
// 从缓存中删除
void remove(K key) throws KvCacheException;
// 根据prefix清理全部数据(这个prefix是我们在配置Policy配置的)
void flush() throws KvCacheException;
}
通过前缀策略,批量删除某个数据组的某个版本的所有数据。
因为我们在通过工厂create cacheWrapper的时候,我们自动在这里的前缀策略默认使用的是:“组名:版本号:”
flush源码:
因为内存资源的珍贵,我们并不能任意的缓存数据库记录到缓存中,如何合理的使用缓存在业务中至关重要。