.Redis 缓存
缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用 DRAM 技术,而使用昂贵但较快速的 SRAM 技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。
Redis 因读写性能较高,它非常适合作为存贮数据的临时地方、成为数据交换的缓冲区,因此在一些大型互联网应用中,Redis 常用来进行数据缓存处理。
Redis 作为缓存,给系统带来了一些好处:
降低后端负载
提高读写效率,降低响应时间
但同时,在项目中使用缓存也会带来一些问题:
数据一致性问题:redis 和 mysql 如何保存数据一致性
代码维护成本:处理缓存穿透、缓存雪崩等问题
运维成本:redis 集群的维护
这些问题是 Redis 作为缓存时必须要考虑的。
2.数据一致性问题
2.1 Redis 缓存更新策略
从 Redis 的角度来说,它的缓存更新策略一般有 3 种,如下表:
在实际的应用中,根据不同的需缓存处理的数据性质,数据的一致性需求存在以下
两种情况:
弱一致性需求:如一些商品类型、客户类型、店铺类型等表示某种类型的数据,一般变动比较少,对这些数据进行缓存处理时,可以使用内存淘汰机制;
强一致性需求:如商品库存、店铺主页、促销、优惠券等数据,经常发生变化,对这些数据进行缓存处理时,可以使用主动更新策略,并以超时剔除作为兜底方案。
2.2 主动更新策略
主动更新策略即更新数据库的同时更新 Redis 缓存,具体实现时,一般使用以下方案:
删除缓存:更新数据库时,删除缓存,让缓存失效,查询时再更新缓存;
保证数据的原子性:单体系统,将缓存与数据库操作放在一个事务,分布式系统,则利用 TCC 等分布式事务方案;
减少并发操作带来的数据错误:先操作数据库,再删除缓存
使用超时剔除机制:当数据写入缓存时,一定设定超时时间
3.缓存穿透
3.1 什么是缓存穿透
缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,缓存永远不会生效。这样,每次针对此 key 的请求从缓存获取不到,请求都会压到数据源,从而可能压垮数据源。比如用一个不存在的用户 id 获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
3.2 解决方案
常用的缓存穿透的解决方案包括:
对空值进行缓存:即使一个查询返回的数据为空,仍然把这个空结果(null)进行缓存,同时还可以对空结果设置较短的过期时间。这种方法实现简单,维护方便,但是会额外的内存消耗。
采用布隆过滤器:(布隆过滤器(Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数)。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
进行实时监控:当发现 Redis 的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务
增强 id 的复杂度,避免被猜测 id 规律
做好数据的基础格式校验
加强用户权限校验
4.缓存雪崩
4.1 什么是缓存雪崩
缓存雪崩是指在同一时段大量的缓存 key 同时失效,或者 Redis 服务宕机,导致大量请求到达数据库,带来巨大压力。
4.2 解决方案
常用的缓存雪崩的解决方案包括:
给不同的 Key 的 TTL 添加随机值
利用 Redis 集群提高服务的可用性
给缓存业务添加降级限流策略
给业务添加多级缓存