首页 > 数据库 >Redis缓存穿透,击穿,雪崩问题改如何解决?

Redis缓存穿透,击穿,雪崩问题改如何解决?

时间:2023-09-19 11:33:05浏览次数:63  
标签:缓存 请求 过期 Redis jedis 雪崩 过滤器 String

无论在开发过程中还是面试过程中,这三个问题总是被遇到。下面是各个问题的原因和解决方案。

缓存穿透


原因

  1. 缓存穿透其实是缓存的单点问题,是指查询一个一定不存在的数据。如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。这种情况大概率是遭到了攻击。
  2. 同时也可能是由于恶意请求或非常罕见的请求导致的,原理同上。如果这种情况频繁发生,会导致大量的请求直接访问底层数据源,增加了系统的负载并降低了性能。

解决方案

缓存空值

public class Cache {
    private Map<String, String> cacheMap;  //这里也可以使用RedisTemplate

    public Cache() {
        cacheMap = new HashMap<>();
    }

    public String getFromCache(String key) {
        // 先从缓存中查找数据
        String value = cacheMap.get(key);

        // 如果缓存中不存在该数据
        if (value == null) {
            // 查询底层数据源
            value = queryDataFromDataSource(key);

            // 如果底层数据源中不存在该数据
            if (value == null) {
                // 将空值缓存起来,防止缓存穿透
                cacheMap.put(key, "");
            } else {
                // 将数据放入缓存
                cacheMap.put(key, value);
            }
        }

        return value;
    }

    private String queryDataFromDataSource(String key) {
        // 查询底层数据源的逻辑
        // ...
        return null; // 假设底层数据源中不存在该数据
    }
}

将空值给缓存起来,这样就减少了数据库的交互。

布隆过滤器

布隆过滤器是一种空间效率高、查询时间快的概率型数据结构,用于判断一个元素是否存在于一个集合中。它可以帮助我们快速判断一个请求是否是恶意请求,从而减轻底层数据源的负载。

以下是使用布隆过滤器来解决缓存穿透问题的具体步骤:

  1. 初始化布隆过滤器:根据预估的数据规模和期望的误判率,初始化一个布隆过滤器。布隆过滤器的大小和误判率是成正比的,需要根据实际情况来选择合适的参数。

  2. 添加元素到布隆过滤器:将所有可能存在于缓存中的关键字都添加到布隆过滤器中。每个关键字经过多次哈希函数计算后,会在布隆过滤器中的对应位上被标记为1。

  3. 查询请求是否存在于布隆过滤器中:当一个请求到来时,先用相同的哈希函数计算出请求的关键字。然后检查布隆过滤器中对应的位是否都为1。如果所有位都为1,说明请求可能存在于缓存中;如果有任何一位为0,说明请求一定不存在于缓存中。

  4. 进一步验证请求:如果布隆过滤器判断请求可能存在于缓存中,那么可以进一步查询缓存来验证请求的确切结果。如果布隆过滤器判断请求一定不存在于缓存中,可以直接返回缓存不存在的结果,避免查询底层数据源。

    import com.google.common.hash.BloomFilter;
    import com.google.common.hash.Funnels;
    
    public class BloomFilterExample {
        public static void main(String[] args) {
            // 创建一个布隆过滤器,预期插入的元素数量为10000,期望的误判率为0.1%
            BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.unencodedCharsFunnel(), 10000, 0.001);
            
            // 向布隆过滤器中添加元素
            bloomFilter.put("exampleKey1");
            bloomFilter.put("exampleKey2");
            
            // 检查元素是否存在于布隆过滤器中
            boolean exists1 = bloomFilter.mightContain("exampleKey1");
            boolean exists2 = bloomFilter.mightContain("exampleKey3");
            
            System.out.println("Exists 1: " + exists1); // 输出: Exists 1: true
            System.out.println("Exists 2: " + exists2); // 输出: Exists 2: false
        }
    }
    

    注意:

    标签:缓存,请求,过期,Redis,jedis,雪崩,过滤器,String
    From: https://www.cnblogs.com/pronting/p/17714201.html

相关文章

  • 一次访问Redis延时高问题排查与总结
    一次访问Redis延时高问题排查与总结https://mp.weixin.qq.com/s/f3dQIC4DBhWibyXQKBXrzg实战总结|一次访问Redis延时高问题排查与总结(续)https://mp.weixin.qq.com/s/trbGNYZPEfzaAMz6kZ_YKg翻译搜索复制......
  • Redis 全景解析
     Redis解析信息图什么是Redis?Redis("REmote DIctionary Service"的缩写)是一个开源的键值数据库服务器。对Redis最准确的描述是它是一个数据结构服务器。Redis的这种特定性质使其在开发人员中非常受欢迎和广泛采用。与其对行进行迭代、排序和排列,不如从头开始使用数......
  • centos7安装redis
    1.普通安装,非最新版本yuminstallredis2.yum安装最新redis如果要安装最新的redis,需要安装Remi的软件源,官网地址yuminstall-yhttp://rpms.famillecollet.com/enterprise/remi-release-7.rpmyum--enablerepo=remiinstallredis-y3.启动redisserviceredisstart#......
  • nginx-缓存
    缓存内容并定义缓存的存储位置。proxy_cache_path/var/nginx/cache               keys_zone=CACHE:60m               levels=1:2                        ......
  • ProxmoxVE上用LVM缓存让SSD加速HDD
    在ProxmoxVirtualEnvironment(ProxmoxVE)上使用LVM缓存来加速机械硬盘的步骤如下:注意:在执行这些步骤之前,请务必备份您的数据。1.确保硬件和分区准备好:确保您的系统中有一个SSD设备和一个机械硬盘(HDD)。SSD用于缓存,HDD用于存储。对SSD和HDD分区并创建物理卷(PV),如果尚......
  • 使用 redis 实现分布式接口限流注解 RedisLimit
    前言很多时候,由于种种不可描述的原因,我们需要针对单个接口实现接口限流,防止访问次数过于频繁。这里就用redis+aop实现一个限流接口注解@RedisLimit代码点击查看RedisLimit注解代码importjava.lang.annotation.*;/***功能:分布式接口限流注解*@authorlove......
  • 分布式缓存
    集群/垂直架构缓存:1集群架构(1-2):集群架构1:a.所有业务都访问同一个集中式缓存.b.业务是混合进行部署,业务划分不清楚.集群架构2(多个应用单独部署):a.不同的业务做独立的划分,独立的部署.b.每种业务使用独立缓存,从业务层将缓存进行互相隔离,防止互相影响.c.业务项目......
  • Redis学习之共享session(单点登录)
    介绍为什么需要共享session?防止多个后端服务器的数据存储不一致,导致用户访问时出现未登录的情况。如何实现共享session?使用独立的内存存储来存放session实现key如何设计?为了安全性,随机生成token,而不是拼接用户信息,防止恶意伪造或爆破。选择何种value数据结构存放用户信......
  • redis配置参数说明
    redis.conf配置文件说明##########ADVANCEDCONFIG###########指定是否激活重置哈希,默认为开启activerehashingyes#aofrewrite过程中,是否采取增量"文件同步"策略,默认为"yes",而且必须为yes.rewrite过程中,每32M数据进行一次文件同步,这样可以减少"aof大文件"写入对磁盘......
  • redis主从复制
    相关配置a.replica-read-onlyyes:从节点开启只读模式b.master-authxxxx:主节点访问密码c.replicaofip端口:从哪个主节点进行复制相关命令inforeplication查看主从信息主从复制分类主从刚连接的时候,会进行全量同步;全同步后,会进行增量同步。a.全量复制 i.mast......