分布式锁结合SpringCache
1、高并发缓存失效问题:缓存穿透:指查询一个一定不存在的数据 , 由于缓存不命中导致去查询数据库 , 但数据库也无此记录 , 我们没有将此次查询的null写入缓存 , 导致这个不存在的数据每次请求都要到存储层进行查询 , 失去了缓存的意义;
风险:利用不存在的数据进行攻击让数据库压力增大最终崩溃;
解决:对不存在的数据进行缓存并加入短暂的过期时间;
缓存雪崩:缓存雪崩是指我们在设置缓存时key采用相同的过期时间 , 导致缓存在某一个时刻同时失效 , 请求全部转发到DB , DB瞬间压力过重雪崩;
解决:原有的失效时间基础上增加一个随机值;
缓存击穿:对于一些设置过期时间的key , 如果这些key会在某个时间被高并发地访问 , 是一种非常“热点”的数据;如果这个key在大量请求同时进来前正好失效 , 那么所有对这个key的数据查询都落在db , 我们称之为缓存击穿
解决:加锁 。 大量并发情况下只让一个人去查 , 其他人等到 , 查到数据后释放锁 , 其他人获取到锁后先查缓存 , 这样就不会出现大量访问DB的情况 。
2、加锁解决击穿问题2.1、加本地锁“确认缓存”与“查询数据库”完成后才释放锁 , 图示:
文章插图
改进后(将“确认缓存”、“查数据库”、“结果放入数据库“都放入锁中):
文章插图
代码部分:public Map> getCatalogJsonFromDbWithLocalLock() {//加锁 , 只要是同一把锁就锁柱所有线程 , 例如:100w个请求用同意一把锁synchronized (this) {//得到锁后再去缓冲中查看 , 如果缓存没有再去查看,有则直接取缓存 。 但是使用“this”只能锁住本地服务 , 所以要使用分布式锁return getDataFromDb();}}private Map> getDataFromDb() {//得到锁后再去缓冲中查看 , 如果缓存没有再去查看,有则直接取缓存 。 但是使用“this”只能锁住本地服务 , 所以要使用分布式锁String catalogJSON = redisTemplate.opsForValue().get("catalogJSON");if (!StringUtils.isEmpty(catalogJSON)) {//如果缓存不为空直接返回Map> result = JSON.parseObject(catalogJSON, new TypeReference
推荐阅读
- Kensington发布StudioDock 将iPad Pro扩展坞与无线充电器相结合
- 为中国医疗健康产业护航,“医工结合”的机会和趋势在哪里?
- java 从零实现属于你的 redis 分布式锁
- 荣耀游戏本实测分享“性能与智能”完美结合
- 中医与人工智能结合,是必然趋势还是双刃剑?
- HarmonyOS 2.0手机开发者Beta版真来了!快来升级EMUI11提前感受分布式技术
- 四核强性能,华硕XD4灵耀AX魔方分布式路由评测
- 为升级鸿蒙做准备 EMU 11分布式技术提前预演
- 分布式天花板?阿里百万架构师的ZK+Dubbo笔记,颠覆认知
- 为什么分布式云是下一代云计算?Gartner分析师这样解释
