欢迎来到"雪碧聊技术"CSDN博客!
在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将不断探索Java的深邃世界,分享最新的技术动态、实战经验以及项目心得。
让我们一同在Java的广阔天地中遨游,携手提升技术能力,共创美好未来!感谢您的关注与支持,期待在"雪碧聊技术"与您共同成长!
目录
5、根据上述思路,自己完成一个练习:给"店铺类型"查询业务添加缓存
1、根据id查询店铺时,如果缓存未命中,则查询数据库,并将结果写入redis,此时要加一个超时时间TTL,来做一致性的兜底。
一、什么是缓存?
1、定义
缓存就是数据交换的缓冲区(称作"Cache"),是存储数据的临时地方,一般读写性能较高。
2、使用缓存的好处
- 降低后端负载:热点数据不用频繁查询数据库,而是直接从redis缓存中获取。
- 提高读写效率,降低响应时间
3、使用缓存的坏处
- 数据一致性成本:修改数据库中的数据后,缓存中的对应数据还是旧版本,这就叫数据不一致。
- 代码维护成本:我们修改数据库的数据后,要及时更新缓存中的数据,保证数据一致性。
- 运维成本:为了避免缓存雪崩、保证缓存高可用,一般会将缓存搭建成集群模式,而这种模式需要很大运维成本。
二、添加Redis缓存
1、场景
2、缓存作用模型
3、代码实现
java
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public Result queryById(Long id) {
String key = CACHE_SHOP_KEY + id;
//1、从Redis中查询商铺缓存
String shopJson = stringRedisTemplate.opsForValue().get(key);
//2、判断redis是否存在
if(StrUtil.isNotBlank(shopJson)){
//3、存在,则直接返回
Shop shop = JSONUtil.toBean(shopJson, Shop.class);
return Result.ok(shop);
}
//4、不存在,根据id查询数据库
Shop shop = getById(id);//该方法,来自mybatisPlus
//5、数据库也不存在,返回错误
if(shop == null){
return Result.fail("店铺不存在!");
}
//6、数据库中存在,则写入redis,并返回给前端
stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop));
//7、返回
return Result.ok(shop);
}
}
4、测试运行效果
第一次访问该页面时,会发现先查数据库,然后将数据放入redis中,并返回给前端
我们再次访问该页面:
此时发现直接从redis中获取到的店铺信息,而根本没查询数据库。
5、根据上述思路,自己完成一个练习:给"店铺类型"查询业务添加缓存
三、缓存更新策略
缓存更新策略,是为了让数据库修改时,redis中的旧数据也得到更新。
1、缓存更新策略有哪些?
- 内存淘汰(redis自带的)
- 超时剔除(加一个有效期TTL)
- 主动更新(自己主动编码)
那种很少变动的信息,就不用管。
那种经常被修改的数据,需要我们自己编写代码,在修改数据库的同时,也更新缓存。
2、主动更新策略
- 自己主动编码,修改数据库的同时更新缓存(最终采用的)
- 租一个服务,帮我们进行缓存与数据库的一致性管理。(麻烦,不采用)
- 我们只操作缓存的内容,然后有一个线程将缓存的最新数据更新到数据库。(麻烦,不采用)
思考:
3、结论
我们的缓存更新策略是:
①修改数据库时,手动编写代码删除redis中的缓存
②并且是先修改数据库,再删除redis的缓存数据。
③在往redis中存数据时,要加入超时时间TTL,来做兜底。
四、案例:给查询商铺的缓存添加超时剔除和主动更新的策略
1、根据id查询店铺时,如果缓存未命中,则查询数据库,并将结果写入redis,此时要加一个超时时间TTL,来做一致性的兜底。
2、根据id修改店铺时,先修改数据库,再删除缓存
java
@Override
@Transactional //保证该方法的所有操作,是一个事务(要么全部成功,要么全部失败)
public Result update(Shop shop) {
Long id = shop.getId();
if(id == null){
return Result.fail("店铺id不能为空");
}
//1、更新数据库
updateById(shop);
//2、删除缓存
stringRedisTemplate.delete(CACHE_SHOP_KEY + id);
return Result.ok();
}
注意:上面用到了@Transactional注解,来保证该方法的所有操作在一个事务内。
3、重启项目,演示效果
第一次访问该页面,redis缓存未命中,于是查询数据库id为1的店铺,并将结果存入redis中,设置有效期为30分钟。如下:
利用postman发送一个修改店铺的信息,如下:
此时就去除了redis中陈旧的店铺信息了。
然后再次访问该餐厅:
以上就是关于店铺信息缓存的redis主动更新的解决方案。
以上就是本文章的全部内容,想了解后续内容,请关注本专栏的后续文章~~