redis-缓存击穿\穿透\雪崩

本文探讨了高并发场景下缓存系统面临的三大挑战:击穿、穿透和雪崩现象。击穿指缓存失效导致大量请求直接访问数据库;穿透则是请求的数据在数据库中不存在;雪崩则因大量缓存同时失效引发。文章提出了相应的解决方案,如使用锁机制、布隆过滤器和随机过期时间等。

击穿

**高并发**请求下,key过期或者LRU,LFU进行了清除。导致大量请求并发访问数据库
阻止并发到数据库
1get key  获得key
2,setnx    设置锁
3-1,ok,去 DB  获取到锁,去数据库查
3-2falsesleep  -> 1   没有获取到锁,休眠一段时间,重复一步骤。或者设置key存在后直接返回

zookeeper

穿透

从业务接收查询的是数据库中根本不存在的数据
布隆过滤器,位图存储是否存在数据,存在就去查库(有小于1%穿透可能),不存在就直接返回。但是不能删除,可以使用布谷鸟过滤器。或者设置空key,直接返回,不到达布隆

雪崩

大量的key同时失效,间接造成大量的访问到达DB
时点性无关,使用随机过期时间
否则在零点进行大批量失效后,业务层延时零点,在数据换血后,进行访问。或者强依赖击穿方案,设置锁,获取到锁,查库,设置值。
### Redis缓存击穿穿透雪崩现象及其解决方案 #### 缓存击穿 当一个热点 key 的过期时间设置不合理,恰好在这个 key 过期的时候有大量的请求并发访问这个 key,则这些请求会全部打到数据库上造成瞬时压力过大。这种情况被称为缓存击穿。 为了防止这种状况的发生,可以采用如下措施: - 设置永不过期的时间戳来避免大量查询直接冲击 DB[^1]。 ```python import time from redis import Redis def get_data_with_fallback(redis_client, key): data = redis_client.get(key) if not data: with distributed_lock(key): # 使用分布式锁确保只有一个线程能执行这段代码 data = fetch_from_db(key) # 假设这是获取数据的方法 if data is None: redis_client.setex(key, "null", timeout=60) # 存储空值并设定较短的有效期 else: redis_client.set(key, data) return data ``` #### 缓存穿透 对于不存在的数据,如果每次都被查到 Redis 和底层存储中均未命中,那么恶意攻击者可能利用此漏洞频繁发起非法请求,从而导致服务器资源浪费甚至崩溃。这便是所谓的缓存穿透问题。 针对这一情况,建议采取以下方法之一或组合使用多种方式加以防范: - 利用布隆过滤器提前判断是否存在该条记录; - 对于查询结果为空的情况也进行缓存处理,并给予一定时限内的有效期; ```python class CacheLayer: def __init__(self, bloom_filter, redis_client): self.bloom_filter = bloom_filter self.redis_client = redis_client def check_and_fetch(self, item_id): if not self.bloom_filter.contains(item_id.encode()): return {"status": False} cached_result = self.redis_client.get(f'item:{item_id}') if cached_result is None: actual_result = database_query(item_id) # 获取真实数据逻辑 if not actual_result["exists"]: self.redis_client.setex( f'missed_item:{item_id}', 'false', ex=300) # 将缺失项加入缓存一段时间 elif isinstance(actual_result['data'], dict): self.redis_client.hmset(f'item:{item_id}', actual_result['data']) return actual_result return {'status': True, **json.loads(cached_result)} ``` #### 缓存雪崩 在同一时刻有大批量的 cache 同步失效,进而引发大量的 db 查询操作,最终可能导致整个系统瘫痪。这就是所说的缓存雪崩事件。 为了避免此类事故的发生,推荐实施下列策略: - 实施主从复制架构下的 Redis 高可用集群部署方案,以便在主节点发生故障时自动切换至备用节点继续提供服务[^2]; - 给不同类型的缓存配置不同的过期间隔,使得它们不会集中在同一时间段内到期; - 应用限流算法控制流量峰值,减轻突发情况下对后端的压力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值