对比各种方案的优缺点
一、缓存DB一致性问题
二、缓存雪崩
2.1 概念
指大量请求无法在缓存进行处理,紧接着请用将大量请求发送到数据库层,导致数据库压力剧增。
2.2 产生原因
1、缓存中大量数据同时过期,导致大量请求在这时间点无法在缓存得到处理;
2、redis实例发生故障宕机,导致不能提供服务。
2.3 第一条原因的解决方案
2.3.1 方案一
设置过期时间时候,可以增加一个较短随机时间,这样可以避免大量数据同时过期,同时由于随机时间较短,也满足了业务要求。
2.3.2 方案二
服务降级,比如当大量缓存同时过期,业务应用访问的是非核心业务时,可以直接返回预定义信息、空值或错误信息。
2.4 第二条原因的解决方案
事后处理:熔断或访问DB限流。
事前预防:搭建高可用集群(哨兵集群)
三、缓存击穿
3.1 概念
某个访问非常频繁的热点数据突然失效,导致大量对这个热点key的请求都打到数据库上。
3.2 解决方案
方案一
非常热点的key不设置过期时间
方案二
使用分布式锁。
请求发现缓存不存在后,去查询 DB 前,使用分布式锁,保证有且只有一个线程去查询 DB ,并更新到缓存。
3.3 方案对比
四、缓存穿透
4.1 概念
指要访问的数据既不在缓存中,也不在数据库中。那么请求访问缓存时,没有命中,去访问数据库,结果数据库中也没有,无法更新缓存。如果有大量这种请求涌入,就会给缓存和数据库造成巨大压力。
一般有两种情况会导致缓存穿透,第一种是缓存和数据库中的数据被误删除了;第二种是恶意攻击。
4.2 解决方案
4.2.1 方案一 缓存null
发生缓存穿透时,可以给缓存一个空值或者业务约定的缺省值(比如库存为0)并设置一个较短的过期时间,那么后续请求来的时候可以避免穿透缓存到达数据库了。
4.2.2 方案二 bloom过滤器
BloomFilter的工作原理!
4.3 方案对比
五、如何应对变慢的Redis
5.1 问题认定
如何判断redis是不是变慢了呢?
判断的方法是看响应延迟+基线性能。响应时间可以通过命令执行redis的时间来判断,基线性能指的是系统在无压力、无干扰的的情况下的基本性能,这个性能只能有当前系统的软硬件配置决定。
测试基线性能我们运行下面的命令,该命令会打印 120 秒内监测到的最大延迟(服务端直接执行,避免网络影响):
./redis-cli --intrinsic-latency 120
这时候我们拿响应延迟和基线性能进行对比。比如基线性能已经达到9.87ms,响应延迟是10ms,那么运行时延迟只比基线性能高1.3%,那么这就不算性能变慢。如果你不了解基线性能,一看到较高的运行时延迟,就很有可能误判 Redis 变慢了。
5.2 排查和解决方法(从redis自身角度分析)
1、从慢查询命令开始排查,并根据业务需求替换慢查询命令。我们可以通过官方文档找出各个命令的时间复杂度,减少使用复杂度高的命令。
2、如果很多key在同一时间过期,那么当过期时,触发的缓存删除策略会占用资源(怎么占用的?)。所以我们要排查过期key的时间设置,可以根据业务适当的加上一个一定大小范围的随机数。
5.3 从文件系统和操作系统层面来分析解决方法(当从redis自身角度没发现问题时)
5.3.1 为什么要关注文件系统和操作系统呢?
redis要持久化保存数据到磁盘,这个过程要依赖文件系统来完成,所以,文件系统将数据写回磁盘的机制,会直接影响到 Redis 持久化的效率。而且,在持久化的过程中,Redis 也还在接收其他请求,持久化的效率高低又会影响到 Redis 处理请求的性能。
另一方面,Redis 是内存数据库,内存操作非常频繁,所以,操作系统的内存机制会直接影响到 Redis 的处理效率。比如说,如果 Redis 的内存不够用了,操作系统会启动 swap 机制,这就会直接拖慢 Redis。