Redis系列复习笔记--缓存

Redis系列复习笔记–缓存

系列文章目录

第五章 Redis系列复习笔记–持久化
第七章 Redis系列复习笔记–Reids集群
第九章 Redis系列复习笔记–缓存



九、缓存

Redis通常还被用做分布式缓存。因为缓存通常都是全内存的(例如Redis、Memcache),而存储层通常读写性能不够强悍(例如MySQL),通过缓存的使用可以有效地加速读写,优化用户体验。 另外,还可以降低后端负载,帮助后端减少访问量和复杂计算。
当然缓存的增加也会带来成本的:数据不一致性,缓存层和存储层的数据有时间差;代码维护成本和运维成本等。

9.1 缓存穿透

缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中。所以每次这种“空key”查询都要透过缓存层经过存储层进行查询,导致存储层压力变大而缓存层形如空设。
造成缓存穿透的基本原因有两个。第一,自身业务代码或者数据出现问题,第二,一些恶意攻击、爬虫等造成大量空命中。
解决办法可以根据业务在接口层做校验避免;也可以使用缓存空对象和布隆过滤器来避开。

9.2 缓存击穿

短时间内某个或某些key被大量请求,且缓存中没有(一般是过期了)直接访问存储层。出现的原因比如秒杀活动某些热点key刚好过期。
解决办法可以在接口层做限流或加锁保证同一时间只有一个线程更新缓存;也可以设置热点key不过期或在即将过期前异步更新缓存并重设过期时间。

9.3 缓存雪崩

短时间内大量并发请求的数据没有命中缓存而直接请求到存储层,导致存储层压力陡增甚至宕机。出现的原因有可能是缓存层服务宕机,也有可能大量数据同时过期。
解决办法包括:均匀设置过期时间;缓存层(比如Redis)宕机是有服务熔断或降级机制。

9.4 数据一致性

增加了缓存,那么就引入了一个问题:先更新缓存再更新数据库?还是先更新数据库在更新缓存。其实两者在高并发下都是有问题,如下图所示。
在这里插入图片描述

无论是先更新缓存再更新数据库还是先更新数据库在更新缓存,都有可能拿到旧值。那如果将更新缓存改成删除缓存,让其它线程拿不到缓存再到数据库请求呢?也是同样存在问题的,有可能某一线程在数据库未被更新前更快地从数据拿到数据并更新缓存为旧值了。那如果采用双删,即先删除缓存更新数据库再删除缓存呢?一样存在上面的问题,只是能保证再二次删除后其它线程不会再拿到旧值。
那要如何保证数据一致性呢?这里的保险做法是使用分布式锁。先更新数据库再删除缓存(一般我们认为更新数据库耗时远大于删除缓存)。保证两个步骤是一个原子操作。同时最好有重试机制,这是由于再操作第二步出错时可以兜底重试,失败一定次数返回错误;而不至于数据库更新成功后其它请求依然拿到旧缓存。

参考文献

1、书籍《Redis开发与运维》
2、redis文档:https://redis.io/docs/latest/develop/
3、redisson文档:https://github.com/redisson/redisson/wiki/Table-of-Content
4、jedis文档:https://redis.io/docs/connect/clients/java/
5、https://pdai.tech/md/db/nosql-redis/db-redis-overview.html
6、https://xiaolincoding.com/redis/base/redis_interview.html#lru-%E7%AE%97%E6%B3%95%E5%92%8C-lfu-%E7%AE%97%E6%B3%95%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB
7、其它

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值