提起redis,毫无疑问,缓存是Redis当今最为人熟知的使用场景。再提升服务器性能方面非常有效。但是,redis不是万金油,它也有自身的弊端,我们在使用redis缓存功能是也会出现一些问题,比如说:
缓存穿透:也就是说查询数据库中一定没用的数据,redis当中肯定也没有,这样的话,每次请求都会发送到数据库中,增加数据库的负担。
解决方案:
- 将每次查不出来的数据当成null存入redis中,这样查询之后直接返回null,但是这种方法不推荐使用
- 布隆过滤器,这里不多做介绍,上篇已经解释过,有兴趣可以去看看
缓存雪崩:缓存在某一时间段大面积失效
解决方案:设置缓存过期时间,缓存时间相同的,失效的时间也是相同的;缓存多个key时,把时间错开。
redis的缓存过期策略
redis的内存回收机制主要围绕两个方面:
1.Redis过期策略:删除过期时间的key值
2.Redis淘汰策略:内存使用到达maxmemory上限时触发内存淘汰数据
redis的过期策略主要有三种:
- 定时过期
每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。 - 惰性过期
只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。 - 定期过期
每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
redis的内存淘汰策略
介绍
-
当 Redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换 (swap)。交换会让 Redis 的性能急剧下降,对于访问量比较频繁的 Redis 来说,这样龟速的存取效率基本上等于不可用。
-
在生产环境中我们是不允许 Redis 出现交换行为的,为了限制最大使用内存,Redis 提供了配置参数 maxmemory 来限制内存超出期望大小。
-
当实际内存超出 maxmemory 时,Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己决定该如何腾出新的空间以继续提供读写服务。
1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。