分布式缓存

缓存的淘汰策略

​ 数据过期策略:惰性删除、定期删除

惰性删除:访问一个key时,Redis先检查它的过期时间,若发现过期立即删除

定期删除:将设置了过期时间的key放入一个独立字典中;对该字典进行每秒10次的扫描,并删除扫描到的已过期的key;

​ 扫描采用贪心策略,每次随机20个key,若已过期比例超过25%则再次随机。

内存淘汰策略:当写入数据发现超过maxmemory时,采用指定的淘汰策略进行删除。

LRU:按照最近最少使用原则筛选数据,最不常用的数据会被筛选出来。

LFU:先统计访问次数,将访问次数最低的淘汰;若访问次数相同,则比较访问时间,访问时间早的淘汰。

内存淘汰策略

描述

noeviction

直接返回错误

volatile-ttl

从设置过期时间的key中,选择过期时间最小的key,进行淘汰

volatile-random

从设置过期时间的key中,随机选择key,进行淘汰

volatile-lru

从设置过期时间的key中,使用LRU算法选择key,进行淘汰

volatile-lfu

从设置过期时间的key中,使用LFU算法选择key,进行淘汰

allkeys-random

从所有的key中,随机选择key,进行淘汰

allkeys-lru

从所有的key中,使用LRU算法选择key,进行淘汰

allkeys-lfu

从所有的key中,使用LFU算法选择key,进行淘汰

常见问题

缓存穿透:客户端查询根本不存在的数据,使得请求直达存储层,导致其负载过大,甚至宕机。

​ 也可能是业务层误将缓存和库中数据删除了,也可能是有人恶意估计,专门访问数据库中不存在的数据

解决:1、缓存空对象:存储层未命中后,仍将空值存入缓存层,客户端再次访问数据时,缓存层会直接返回空值

​ 2、布隆过滤器:将数据存入布隆过滤器,访问缓存之前过滤器拦截,若请求的数据不存在则直接返回空值

缓存击穿:一份热点数据,访问量非常大。在其缓存失效的瞬间,大量请求直接抵达存储层,导致服务的崩溃。

解决:1、永不过期:热点数据不设置过期时间/为每个数据设置逻辑过期时间,当发现该数据逻辑过期时,使用单独的线程重建缓存

​ 2、加互斥锁:对数据的访问加互斥锁,当一个线程访问时,其他线程只能等待。

缓存雪崩:在某一时刻,缓存层无法在提供服务,导致所有的请求直接抵达存储层,造成数据库的宕机。

​ 可能是缓存中有大量数据同时过期,也可能是Redis节点发生故障,导致大量请求得不到解决

解决:1、避免数据同时过期,设置过期时间时,附加一个随机数,避免大量的key同时过期

​ 2、启用降级和熔断措施,在发生雪崩时,若访问的不是核心数据,则直接返回预定义信息/空值/错误信息;对于访问缓存接口的请求,客户端并不会把请求发给Redis,而是直接返回。

​ 3、构建高可用的缓存服务,采用哨兵或者集群,部署多个Redis实例,个别节点的宕机,依然可以保证节点的可用性。