首页 > 其他分享 >深入理解 Bitmap 应用于缓存穿透与解决方案

深入理解 Bitmap 应用于缓存穿透与解决方案

时间:2024-10-22 13:47:36浏览次数:8  
标签:缓存 id 穿透 ID Bitmap public size

文章目录


缓存穿透问题表面上看似复杂,实际上它的本质非常简单:当请求数据库中不存在的数据时,由于 Redis 缓存中没有缓存这些结果,查询每次都会直接穿透到数据库。这种情况可能源于恶意攻击或不合理的查询设计。如果不加以控制,将对数据库造成巨大压力,影响系统性能。

常见的解决方案

方案一:ID 校验(检查 ID 是否小于零)

一个直接有效的方案是对传入的 ID 进行简单校验,例如判断 ID 是否小于 0。因为在大多数应用场景中,数据的 ID 通常为非负数。如果 ID 小于零,则可以直接返回错误或空结果。这种方式能够有效减少无效请求穿透缓存和数据库,减轻系统负担。

public boolean isValidId(int id) {
    return id >= 0;
}

方案二:缓存空结果

另一种常见的方案是将数据库查询结果为空的情况也缓存到 Redis 中,并设置一个较短的过期时间(例如 5 分钟)。这种方式在一定程度上可以避免重复查询同一个不存在的键值。但是,当大量不同的无效 ID 请求出现时,Redis 会存储大量空数据,从而增加缓存的存储压力,导致 Redis 性能下降。

public void cacheEmptyResult(String key) {
    // 假设我们有一个 Redis 工具类 RedisUtil
    RedisUtil.set(key, "", 300); // 缓存空值,过期时间为300秒
}

进阶方案:列表验证合法性

在某些复杂场景下,我们可以维护一个合法 ID 列表,查询时先检查这个 ID 是否在合法列表中,如果不在则直接返回错误。这种方式在过滤无效请求方面非常有效,可以极大减少对数据库的访问。

然而,维护如此大规模的 ID 列表是非常耗费内存的,尤其是当系统中存在大量数据时。例如淘宝的商品总量在2011年就已超过10亿个,维护一个如此庞大的列表会带来巨大的内存开销和管理复杂性。

public boolean isIdInValidList(int id, Set<Integer> validIds) {
    return validIds.contains(id);
}

使用 Bitmap 优化存储空间

为了优化存储空间,可以使用 Bitmap 结构替代传统列表。Bitmap 是一种高效的位存储结构,特别适合需要存储大量布尔值的场景。其基本思想是将每个合法的数据库 ID 映射到 Bitmap 的某个位上。

具体而言,我们可以通过哈希函数 id % bitmap.size 计算出 ID 在 Bitmap 中的位置,并将该位置的值置为 1,表示该 ID 存在。请求数据时,系统先计算请求 ID 在 Bitmap 中的位置,如果该位为 0,表示该 ID 不存在,可以直接返回结果,避免了对数据库的查询。

Java 实现示例:

import java.util.BitSet;

public class CachePenetrationSolution {
    private BitSet bitMap;
    private int size;

    public CachePenetrationSolution(int size) {
        this.size = size;
        this.bitMap = new BitSet(size);
    }

    // 将有效ID标记到Bitmap中
    public void addToBitmap(int id) {
        int index = id % size;
        bitMap.set(index);
    }

    // 检查ID是否存在于Bitmap中
    public boolean isIdInBitmap(int id) {
        int index = id % size;
        return bitMap.get(index);
    }

    public static void main(String[] args) {
        CachePenetrationSolution solution = new CachePenetrationSolution(1000000);
        
        // 将一些有效ID加入Bitmap
        solution.addToBitmap(1001);
        solution.addToBitmap(1002);

        // 查询ID是否存在
        System.out.println(solution.isIdInBitmap(1001)); // true
        System.out.println(solution.isIdInBitmap(9999)); // false
    }
}

优化提示:结合布隆过滤器减少误判

虽然 Bitmap 非常高效,但它也会带来一些误差。由于哈希函数存在碰撞的可能性,不同的 ID 可能会映射到同一个 Bitmap 位置,导致误判。为了解决这一问题,可以引入布隆过滤器(Bloom Filter),其通过多个哈希函数有效减少误判率,从而进一步提升系统的准确性和效率。

方案总结

缓存穿透问题虽然看似简单,但实际解决过程需要我们针对不同场景选择合适的方案。基础方案如 ID 校验和缓存空值可以解决部分问题,而在面对大规模数据的情况下,Bitmap 提供了一种高效的解决方法。结合布隆过滤器进一步优化后,不仅能够降低存储空间占用,还能有效减少误判,极大提高系统的性能和稳定性。

标签:缓存,id,穿透,ID,Bitmap,public,size
From: https://blog.csdn.net/Takumilove/article/details/143144839

相关文章

  • 域渗透之 内网穿透 隧道技术聊聊看 环境搭建 regeorg技术 proxifier联合使用 一步步让
    Http通道ReGeorg环境搭建win10安装reGeorgwin2003phpstudywin7安装phpstudy软件下载地址通过网盘分享的文件:隧道工具链接:https://pan.baidu.com/s/1Jmh2QbfmIPRdeTuWN9-Dkg?pwd=k81v提取码:k81v试验步骤在win2003和win10之间建立一个隧道那么就将regeorg......
  • 一文彻底弄懂并解决Redis的缓存雪崩,缓存击穿,缓存穿透
    缓存雪崩、缓存击穿、缓存穿透是分布式系统中使用缓存时,常遇到的三类问题,都会对系统性能和稳定性产生严重影响。下面将详细介绍这三者的定义、产生原因、危害以及常见的解决方案。1.缓存雪崩1.1定义缓存雪崩是指在某一时刻,大量缓存同时失效,导致大量请求直接打到数据库层,造成......
  • PbootCMS缓存如何清理runtime文件夹下经常满怎么办?清理缓存的方法
    方式一:通过后台清理缓存登录后台:打开浏览器,输入你的PbootCMS后台地址,登录后台管理系统。清理缓存:登录后,在右上角找到“清理缓存”按钮,点击即可自动清理所有缓存文件。方式二:通过FTP或服务器直接删除runtime文件夹下的所有文件连接FTP服务器:使用FTP客户端(如Fil......
  • 内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)
    内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)-含详细原理配置说明介绍前言远程桌面协议(RDP,RemoteDesktopProtocol)可用于远程桌面连接,Windows系统(家庭版除外)也是支持这种协议的,无需安装额外客户端即可实现类似向日葵、toDesk等的远程桌面访问与控......
  • 位置、Cookie、缓存:华为鸿蒙 ArkWeb 数据管理全攻略
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。引言ArkWeb是华为鸿蒙系统提......
  • Bitmap 和 布隆过滤器傻傻分不清?你这不应该啊
    大家好,我是小富~有个兄弟私下跟我说,他在面试狗东时,有一道面试题没回答上来:Redis的Bitmap和布隆过滤器啥区别与关系?其实就是考小老弟对这两种工具的底层数据结构是否了解,不算太难的题。不过,bitmap和布隆过滤器在大数据量和高并发业务的使用频率不低,知识点应该掌握下,既然问了那咱......
  • pbootcms网站自动清理runtime缓存方法
    为了实现PbootCMS系统自动清理缓存目录,可以按照以下步骤操作:备份文件:在进行任何修改之前,务必备份 /apps/home/controller/ExtLabelController.php 文件,以防出现意外情况。修改 ExtLabelController.php 文件:打开 /apps/home/controller/ExtLabelController.php ......
  • 分布式缓存的基本概念入门以及如何保证数据一致性
    一、分布式缓存基本概念和常见技术框架JavaWeb中的分布式缓存是指在多台服务器之间共享缓存数据的技术。在分布式系统中,单个应用实例通常不会运行在一个单一的服务器上,而是部署在多个节点上以实现负载均衡和高可用性。为了在这些节点之间共享数据,就需要使用分布式缓存技术......
  • 【远程监控新体验】OpenObserve结合内网穿透无公网IP远程访问全攻略
    文章目录前言1.安装Docker2.Docker镜像源添加方法3.创建并启动OpenObserve容器4.本地访问测试5.公网访问本地部署的OpenObserve5.1内网穿透工具安装5.2创建公网地址6.配置固定公网地址前言本文主要介绍如何在Linux系统使用Docker快速本地......
  • ArkWeb页面预加载与缓存 - 提升用户体验
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。简介在Web应用开发中,页面加载速度和......