带你搞明白什么是缓存穿透、缓存击穿、缓存雪崩

本文详细介绍了缓存中的三种异常现象:缓存穿透、缓存击穿和缓存雪崩,以及针对这些问题的解决方案,包括将空数据存入缓存、使用布隆过滤器、自动更新、定时刷新和程序加锁等策略。通过案例分析和代码示例,帮助读者理解如何避免和处理这些潜在的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

文章开始之前先做个找工作的介绍吧,由于这次疫情影响,我一个UI朋友的公司破产之后他现在处于找工作阶段,一直没有找到自己合适的,三年工作经验左右,坐标深圳,如果有招UI的朋友可以联系我。

作品: http://yiming.zcool.com.cn/

缓存是互联网开发中必不可少的一部分,它能降低我们数据库的并发数,提高我们系统的性能,比如我们经常使用的redis、emCached等等,其中redis应该是大部分的人选,为什么?因为速度快,易上手,是很多开发者的首选,但是缓存同样存在这问题,如果使用的不恰当,也可能会造成非常严重的后果,这时候你可能就会有疑问,缓存只是存储一些数据而已,怎么会造成严重的后果呢?下面我就带大家一起来分析分析。

什么是缓存

缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。

比如我们的redis、他就是缓存中比较常见的一种,他的并发读写能力能达到10w/s左右的速度,这个速度是相当不错的,相对于传统的数据存储来说,比如数据库,快了不知道多少倍,传统的数据库(mysql)操作的都是磁盘,而redis操作的是内存(ram),所以他们的速度肯定是没法比较的,由于传统数据库的读写较慢,所以并发较高的时候就会造成性能瓶颈问题,这也是为什么需要引入缓存的原因之一。

人在地上走,锅从天上来

我是一个快乐的程序狗,每天最快乐的事情就是codding,最大的愿望就是能准时6点下班,然后回家,但是今天肯定是走不了了,现在是17:30,我们的测试小哥哥给我提了一个很诡异的bug,难受啊,我的准时下班梦,但是作为一个程序狗,肯定都有着一颗和bug战斗到底的决心,究竟是什么bug呢?

bug是这样的:并发请求订单信息,没过几秒就抛出系统错误。这个bug看着没几个字,但是一看就知道不好解决,尤其是像这种并发bug,能让人瞬间白了头,随后我找到了测试,让他们复现了这个神秘的bug,而我也找到了产生这个bug的来源,并且快速的修复了他,到底是什么问题呢?是因为小明(同事)在编写代码的时候考虑的不是很周全导致的,所以开发一定要想仔细了再动手,否则吃亏的就是自己啊。

缓存穿透

什么是缓存穿透

缓存穿透指的是:同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。

上面的bug也是因为它产生的,测试的小哥哥查询的订单都是数据库不存在的,所以这个时候这些并发请求都不会命中缓存(redis),将直达数据库(mysql),由于大量的并发请求到达数据库,而数据库承受不住这么高的并发,从而导致数据库奔溃,这就是缓存穿透

重现bug

1.新建数据表:订单表,结构如下:
在这里插入图片描述
2.编写测试代码

OrderBo.java

package com.ymy.bo;

import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

@Data
public class OrderBo implements  Serializable {
   
   

    /**
     * 自增id
     */
    private Long id;

    /**
     *订单编号
     */
    private Long orderCode;

    /**
     *订单价格
     */
    private BigDecimal orderPrice;

    /**
     *商品名称
     */
    private String  peoductName;

    /**
     *创建时间
     */
    private String createTime;
}

OrderController.java

package com.ymy.controller;

import com.ymy.bo.OrderBo;
import com.ymy.service.OrderService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {
   
   

    private OrderService orderService;

    public OrderController(OrderService orderService){
   
   
        this.orderService = orderService;
    }

    @RequestMapping(value = "/detail",method = RequestMethod.GET)
    public OrderBo getDetail(@RequestParam("id") Long id){
   
   

        return orderService.getDetail(id);
    }


}

OrderService.java

package com.ymy.service;

import com.ymy.bo.OrderBo;
import com.ymy.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class OrderService {
   
   

    private RedisTemplate redisTemplate;

    private OrderMapper orderMapper;

    public OrderService(RedisTemplate redisTemplate,OrderMapper orderMapper){
   
   
        this.redisTemplate = redisTemplate;
        this.orderMapper = orderMapper;
    }
    /**
     * 通过id查询订单详情
     * @param id
     * @return
     */
    public OrderBo getDetail(Long id) {
   
   

        //缓存中查询词词订单
        OrderBo  orderBo = (OrderBo) redisTemplate.opsForValue
评论 49
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值