缓存 redis 缓存穿透

哪一些因素 考虑使用redis,毕竟 redis 也要增加成本

1 热点数据

2 读的成本非常大

3 读多写少

4 对数据一致性要求 没有那么严格(可以出现数据与数据库不一致)

 

1 秒杀场景

2 微信抢红包

3 物流查询轨迹(热点数据 激活的数据是被缓存到redis 当中)

缓存key 一个时间点过期的时候,如果缓存数据为热点数据,那么在过期时间点超高并发访问这个 key,压力就会传导至数据库挂掉

 

 

解决方法 使用互斥锁, 思路是这样,大并发过来,抢到锁 去请求数据库,请求成功,设置到 redis 中,其他没有抢到的 sleep 一秒,这个时候,缓存中已经有数据,这样 其他查询 都会获取缓存中的数据,问题解决

static Lock reenLock = new ReentrantLock();
 
    public List<String> getData04() throws InterruptedException {
        List<String> result = new ArrayList<String>();
        // 从缓存读取数据
        result = getDataFromCache();
        if (result.isEmpty()) {
            if (reenLock.tryLock()) {
                try {
                    System.out.println("我拿到锁了,从DB获取数据库后写入缓存");
                    // 从数据库查询数据
                    result = getDataFromDB();
                    // 将查询到的数据写入缓存
                    setDataToCache(result);
                } finally {
                    reenLock.unlock();// 释放锁
                }
 
            } else {
                result = getDataFromCache();// 先查一下缓存
                if (result.isEmpty()) {
                    System.out.println("我没拿到锁,缓存也没数据,先小憩一下");
                    Thread.sleep(100);// 小憩一会儿
                    return getData04();// 重试
                }
            }
        }
        return result;
    }

 

缓存击穿,是某一个key在某一个时间点失效,有大量并发请求过来

缓存穿透,是利用自己伪造的key,这个key它在缓存里面一定不存在

 

 

最后 都去查询数据库

 

最简单的方法,所有的key 存到 set 或者 list集合 ,存在 合法请求,不存在 非法请求

 

布隆过滤器 解决过滤器 问题

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<think>我们正在讨论Redis中的缓存穿透缓存击穿问题。根据用户提供的引用材料,我们需要明确这两个概念的区别以及各自的解决方案。注意,用户还提到了缓存雪崩,但问题主要集中在穿透和击穿。 首先,根据引用[1]: - 缓存穿透:个别key没有被命中,导致请求直接作用在数据库上。这种情况是分散的、轻缓的(像一个个点)。 - 缓存击穿:大量请求同时作用在同一个key上,当这个key过期的瞬间,所有请求都打到数据库,导致数据库压力过大(像一条线)。 - 缓存雪崩:大量key集中过期或Redis宕机,导致数据库挂掉(像整个面)。 然后,引用[2][3][4]提供了解决方案。 接下来,我们组织回答: 1. 先分别解释缓存穿透缓存击穿的概念,并强调区别。 2. 分别给出解决方案。 注意:用户要求参考站内引用,因此我们在回答中需要引用这些材料。 回答结构建议: - 缓存穿透 - 概念 - 解决方案(多个方法) - 缓存击穿 - 概念 - 解决方案(多个方法) - 总结区别(可表格对比) 最后,生成相关问题。 注意:回答中需要自然添加引用标识,如[^1][^2]等。同时,确保使用正确的LaTeX格式(虽然这个问题可能数学公式较少,但如果有公式,要按规则书写)。 我们开始构建回答:</think>### Redis 缓存穿透缓存击穿的区别及解决方案 #### **一、核心概念区别** | **问题类型** | **触发条件** | **影响特征** | **形象比喻** | |--------------|----------------------------|-------------------------------------------|----------------------| | **缓存穿透** | 查询**不存在的数据**(如非法ID) | 分散的无效请求穿透Redis直击数据库,压力呈**点状分布** | 雨滴穿透(分散、轻缓)[^1] | | **缓存击穿** | **热点Key突然过期** | 海量请求瞬间压垮数据库,压力呈**线状集中** | 钢针穿刺(集中、猛烈)[^1] | | **缓存雪崩** | 大批Key集中过期或Redis宕机 | 数据库被大面积请求压垮,压力呈**面状覆盖** | 雪山崩塌(广泛、灾难性)[^1] | > 📌 **关键区别**: > - 穿透:**数据本身不存在**(业务逻辑问题) > - 击穿:**热点数据失效**(并发访问问题) --- #### **二、缓存穿透解决方案** 1. **空值缓存** - 将查询为空的Key也存入Redis,设置较短TTL(如30秒)[^4] - 示例代码: ```java if (data == null) { redis.setex("key:null", 30, ""); // 缓存空值 return; } ``` 2. **布隆过滤器** - 在Redis前加布隆过滤器层,拦截非法Key[^4] - 原理: - 使用$k$个哈希函数映射位数组 - 误判率公式:$P \approx (1 - e^{-kn/m})^k$($m$=位数组大小,$n$=元素数) - 实现:RedisBloom模块或Guava库 3. **请求校验** - 接口层校验参数合法性(如ID范围、格式)[^4] --- #### **三、缓存击穿解决方案** 1. **互斥锁(Mutex Lock)** - 当热点Key失效时,仅允许一个线程重建缓存[^4] - 伪代码: ```java public String getData(String key) { String data = redis.get(key); if (data == null) { if (redis.setnx("lock:" + key, "1")) { // 获取锁 data = db.query(key); // 查数据库 redis.setex(key, 300, data); // 重建缓存 redis.del("lock:" + key); // 释放锁 } else { Thread.sleep(50); // 等待重试 return getData(key); // 递归调用 } } return data; } ``` 2. **逻辑过期** - 缓存永不过期,但存储**逻辑过期时间戳** - 异步更新:当检测到数据过期时,触发后台更新[^4] - 数据结构示例: ```json { "value": "真实数据", "expire_ts": 1715000000 // 逻辑过期时间 } ``` 3. **热点数据续期** - 监控高频访问Key(如Redis监控命令`redis-cli --hotkeys`) - 自动延长TTL:在过期前重置为$新TTL = 原TTL \times 1.5$[^2] --- #### **四、防御组合策略** | **层级** | **穿透防护** | **击穿防护** | |----------------|----------------------------|--------------------------| | **接入层** | 参数校验 + WAF防火墙 | 限流(令牌桶算法) | | **缓存层** | 布隆过滤器 + 空值缓存 | 互斥锁 + 逻辑过期 | | **数据层** | 数据库查询限流 | 连接池控制(如HikariCP) | | **监控响应** | 实时告警非法请求IP | 热点Key自动标记[^2] | > 💡 **最佳实践**: > - 穿透场景:布隆过滤器 + 空值缓存(成本低) > - 击穿场景:互斥锁 + 热点监控(保障强一致性)[^4] --- ### **总结对比** | **维度** | **缓存穿透** | **缓存击穿** | |----------------|----------------------------|----------------------------| | **根本原因** | 数据不存在 | 热点Key瞬时失效 | | **请求特征** | 分散、低效 | 集中、高并发 | | **防御重点** | 拦截非法请求 | 控制重建并发度 | | **核心工具** | 布隆过滤器 | 分布式锁 | 通过分层防御策略,可显著降低数据库压力。例如某电商平台采用布隆过滤器+互斥锁后,数据库QPS峰值下降82%[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值