什么是缓存击穿?如何避免之布隆过滤器

news2024/11/28 7:13:36

缓存击穿(Cache Penetration)是分布式系统和缓存使用中的一个常见问题,布隆过滤器在解决缓存击穿问题时非常有用。接下来我会介绍缓存击穿的概念以及布隆过滤器在解决该问题中的应用。

什么是缓存击穿?

缓存击穿是指当大量的客户端请求访问一个不存在的缓存数据时,这些请求会绕过缓存直接击穿到数据库,给数据库带来巨大压力,甚至可能导致服务瘫痪。这通常发生在以下几种情况下:

  1. 请求的键不存在于缓存中:比如用户在查询一个不存在的商品 ID、文章 ID 等。
  2. 缓存未命中:由于查询到的结果不存在,直接请求数据库,这种请求行为在高并发场景下,会对数据库产生非常大的压力。

缓存击穿的场景

  • 假设你有一个大型电商网站,客户经常搜索商品。某些时候,一些用户会输入随机的 ID 进行商品搜索。如果这些 ID 是无效的,且对应的数据并不在数据库中,查询结果也不会被缓存。这些请求会不断地穿透缓存,直接访问数据库,导致数据库负载过高。
  • 在这种情况下,大量查询无效键的请求绕过缓存,直接访问数据库,使得数据库变得不堪重负,甚至宕机。

布隆过滤器在解决缓存击穿中的应用

布隆过滤器可以有效地解决缓存击穿问题,原因是它可以快速判断一个键是否一定不存在,从而避免对数据库的无效查询。

布隆过滤器如何应用于缓存击穿?
  1. 初始化阶段

    • 在系统启动或初始化时,将所有数据库中的有效键(比如商品 ID)加载到布隆过滤器中。布隆过滤器中记录了所有有效键的信息。
  2. 请求阶段

    • 当客户端请求某个键时,首先使用布隆过滤器进行检查。
    • 布隆过滤器判断
      • 如果布隆过滤器判断该键一定不存在(即返回 false),那么直接返回结果为 “无数据”。
      • 如果布隆过滤器判断该键可能存在(即返回 true),则继续查询缓存。
      • 如果缓存命中,返回缓存结果;如果缓存未命中,查询数据库。
  3. 查询数据库

    • 如果布隆过滤器判断该键可能存在,且缓存也没有结果,最终的查询会走到数据库。
    • 如果数据库也没有结果,通常可以将结果设置为一个“空对象”并加入缓存,以防止短时间内再度访问造成缓存击穿。
布隆过滤器解决缓存击穿的好处
  1. 减少数据库的访问

    • 布隆过滤器在大多数情况下可以直接判断无效的请求,从而不必查询数据库,这样可以减少对数据库的压力。
  2. 高效的存在性判断

    • 布隆过滤器使用位数组和多个哈希函数,可以在常数时间复杂度 O(k)(k 为哈希函数个数)内完成存在性判断,并且占用的空间非常小。
示例:布隆过滤器用于防止缓存击穿

以下是一个简单的示例,演示如何利用布隆过滤器来防止缓存击穿。

import java.util.BitSet;

public class CacheWithBloomFilter {
    private static final int DEFAULT_SIZE = 1000; // 位数组大小
    private static final int[] SEEDS = new int[]{7, 11, 13, 31, 37, 61}; // 哈希函数种子
    private BitSet bits;
    private HashFunction[] hashFunctions;

    public CacheWithBloomFilter() {
        bits = new BitSet(DEFAULT_SIZE);
        hashFunctions = new HashFunction[SEEDS.length];
        for (int i = 0; i < SEEDS.length; i++) {
            hashFunctions[i] = new HashFunction(DEFAULT_SIZE, SEEDS[i]);
        }
        // 模拟初始化阶段,将数据库中有效的数据加载到布隆过滤器
        String[] existingKeys = {"product_1", "product_2", "product_3"};
        for (String key : existingKeys) {
            add(key);
        }
    }

    // 添加元素到布隆过滤器
    public void add(String value) {
        for (HashFunction f : hashFunctions) {
            bits.set(f.hash(value), true);
        }
    }

    // 查询元素是否存在
    public boolean mightContain(String value) {
        for (HashFunction f : hashFunctions) {
            if (!bits.get(f.hash(value))) {
                return false; // 如果有一个哈希值位置为 0,则说明一定不存在
            }
        }
        return true; // 所有位都为 1,则说明可能存在
    }

    // 模拟缓存查询
    public String getFromCache(String key) {
        // 在布隆过滤器中检查是否可能存在
        if (!mightContain(key)) {
            System.out.println("Key '" + key + "' is not in bloom filter, skipping cache and DB lookup.");
            return null; // 一定不存在
        }
        // 模拟缓存查询(这里假设缓存总是未命中)
        System.out.println("Key '" + key + "' might be in bloom filter, continue cache lookup...");
        return null; // 模拟缓存未命中
    }

    // 模拟数据库查询
    public String getFromDB(String key) {
        // 模拟数据库查询(这里假设部分键不存在)
        System.out.println("Querying database for key '" + key + "'...");
        if ("product_1".equals(key) || "product_2".equals(key) || "product_3".equals(key)) {
            return "Valid Product";
        }
        return null; // 数据库中不存在该键
    }

    public static void main(String[] args) {
        CacheWithBloomFilter cache = new CacheWithBloomFilter();

        // 查询不存在的键,布隆过滤器返回一定不存在
        cache.getFromCache("product_100"); // 布隆过滤器直接拒绝

        // 查询可能存在的键
        cache.getFromCache("product_1");
        cache.getFromDB("product_1"); // 继续查询数据库
    }

    // 内部静态类,定义哈希函数
    private static class HashFunction {
        private int cap;
        private int seed;

        public HashFunction(int cap, int seed) {
            this.cap = cap;
            this.seed = seed;
        }

        public int hash(String value) {
            int result = 0;
            for (int i = 0; i < value.length(); i++) {
                result = seed * result + value.charAt(i);
            }
            return (cap - 1) & result; // 返回在 [0, cap) 范围内
        }
    }
}

解释代码

  1. 布隆过滤器初始化

    • 将数据库中所有有效的键(例如 "product_1", "product_2", "product_3")都添加到布隆过滤器中。
  2. 查询流程

    • 当查询一个不存在的键 "product_100" 时,布隆过滤器直接判断该键不存在,从而避免了数据库查询。
    • 当查询一个可能存在的键 "product_1" 时,布隆过滤器判断该键可能存在,于是继续进行缓存查询或者数据库查询。

总结布隆过滤器在缓存击穿中的作用

  • 快速判断无效键:布隆过滤器可以高效地判断某个键是否存在。如果布隆过滤器判定某个键一定不存在,那么请求不会再访问缓存和数据库,从而减少无效请求对系统的压力。
  • 减少数据库压力:通过布隆过滤器,可以有效减少对数据库的无效访问,从而防止缓存击穿给数据库带来的高并发压力。

布隆过滤器的这种使用场景,在实际的大规模系统中非常常见,尤其是在需要减少数据库访问次数、保护数据库负载的系统中,如分布式缓存系统、API 限流、去重等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2248903.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[VSCode] vscode下载安装及安装中文插件详解(附下载文件)

前言 vscode 链接&#xff1a;https://pan.quark.cn/s/3acbb8aed758 提取码&#xff1a;dSyt VSCode 是一款由微软开发且跨平台的免费源代码编辑器&#xff1b;该软件支持语法高亮、代码自动补全、代码重构、查看定义功能&#xff0c;并且内置了命令行工具和Git版本控制系统。 …

wireshark基础

免责声明&#xff1a; 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 泷羽sec官网&#xff1a;https://longyusec.com/ 泷羽sec B站地址&#xff1a;https:/…

李宏毅LLM探索(1)

1引入 1.1 提问&#xff1a;请列出你能做的事情&#xff0c;至少三十项&#xff0c;每一项都简单扼要:然后把你能做的事情制成文字云 文心一言生成&#xff1a; 以下是我能做的至少三十项事情&#xff0c;每一项都简单扼要地列出&#xff1a;回答问题 提供信息 生成文本 理解…

磁盘文件系统问题排查

1. ext4磁盘结构 块组&#xff1a;超级块&#xff1a;块位图&#xff1a;inode位图&#xff1a;inode表&#xff1a;空闲inode表&#xff1a;空闲块表&#xff1a;2. 块组结构 Group 0: (Blocks 0-32767) csum 0xfd42 [ITABLE_ZEROED]Primary superblock at 0, Group descript…

百度雪花算法id默认配置过期注意更新配置

百度雪花id项目地址&#xff1a;GitHub - baidu/uid-generator: UniqueID generator 默认配置根据redme看容易看迷糊&#xff0c;图和配置它压根就不是对应的 默认的配置如下 <!-- Specified bits & epoch as your demand. No specified the default value will be us…

(11)(2.2) BLHeli32 and BLHeli_S ESCs(二)

文章目录 前言 1 传递支持 前言 BLHeli 固件和配置应用程序的开发是为了允许配置 ESC 并提供额外功能。带有此固件的 ESC 允许配置定时、电机方向、LED、电机驱动频率等。在尝试使用 BLHeli 之前&#xff0c;请按照 DShot 设置说明进行操作(DShot setup instructions)。 1 传…

【初阶数据结构和算法】初识树与二叉树的概念以及堆和完全二叉树之间的关系

文章目录 一、树的概念与结构1.树的概念2.树的相关术语3.树的表示4.树形结构实际运用举例 二、二叉树的概念及特殊二叉树1.二叉树的概念2.特殊的二叉树满二叉树完全二叉树二叉树的性质(由满二叉树特点推导) 三、二叉树的存储结构1.二叉树的顺序结构2.二叉树的链式结构 四、堆和…

如何在Canvas中添加背景图片、图片元素和文字元素

Canvas是HTML5中一个强大的元素&#xff0c;它允许我们在网页上进行图形绘制。在本文中&#xff0c;我们将学习如何在Canvas中添加背景图片、图片元素以及文字元素。 创建Canvas元素 首先&#xff0c;我们需要在HTML文档中创建一个<canvas>元素。以下是创建一个500x500像…

单点登录深入详解之设计方案总结

基于cookie的单点登录解决方案 概述 用户登录之后 , 将认证信息存储至 Cookie &#xff0c;当再次访问本服务或者访问其他应用服务时&#xff0c;直接从 Cookie 中传递认证信息&#xff0c;进行鉴权处理。 问题 1. 如何保障Cookie内用户认证信息的安全性? 第一, Cookie…

深入探讨 Redis 持久化机制:原理、配置与优化策略

文章目录 一、引言二、Redis持久化概述三、RDB&#xff08;Redis DataBase&#xff09;持久化1、RDB概念与工作原理2、RDB的配置选项3、RDB优化配置项4、RDB的优势与劣势 三、AOF&#xff08;Append-Only File&#xff09;持久化1、AOF概念与工作原理2、AOF的三种写回策略3、Re…

Java图书管理系统(简易保姆级)

前面学习了这么多知识&#xff0c;为了巩固之前的知识&#xff0c;我们就要写一个图书管理系统来帮助大家复习&#xff0c;让大家的知识融会贯通~~~ 话不多说&#xff0c;直接开始今天的内容~ 首先呢&#xff0c;我们要有一个大体的思路&#xff1a; 实现效果思路有两种情况&a…

网络安全在现代企业中的重要作用

网络安全是这个数字时代最令人担忧的事情之一。对技术的依赖性越来越强&#xff0c;使其同时面临多种网络威胁。其声誉和法律后果的大幅下降可能归因于一次妥协。 这使得良好的网络安全成为所有企业的选择和必需品。本文介绍了网络安全的重要性、企业中常见的网络威胁以及公司…

Zero to JupyterHub with Kubernetes中篇 - Kubernetes 常规使用记录

前言&#xff1a;纯个人记录使用。 搭建 Zero to JupyterHub with Kubernetes 上篇 - Kubernetes 离线二进制部署。搭建 Zero to JupyterHub with Kubernetes 中篇 - Kubernetes 常规使用记录。搭建 Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s。 参考&…

三维天地助力生产制造企业做好产品质量控制

生产制造业已成为全球经济的重要支柱,随着全球化的深入发展,生产制造业的竞争愈发激烈。在生产过程中难以避免的质量波动可能导致产品不良率上升,影响客户满意度和企业声誉。为确保产品质量是受控且优质的,确保生产过程的稳定性,大多数生产制造企业都在进行精细化管理改革,依靠…

IC数字后端实现之大厂IC笔试真题(经典时序计算和时序分析题)

今天小编给大家分享下每年IC秋招春招必考题目——静态时序分析时序分析题。 数字IC后端笔试面试题库 | 经典时序Timing计算题 时序分析题1&#xff1a; 给定如下图所示的timing report&#xff0c;请回答一下几个问题。 1&#xff09;这是一条setup还是hold的timing report?…

arcgis for js FeatureLayer和GeoJSON一个矢量点同时渲染图形和文本

效果 FeatureLayer和GeoJSONLayer, 一个矢量点同时渲染图形和文本 代码 相关参数自行查阅文档, 这里就不做注释了 示例代码手动创建FeatureLayer方式, 如果是通过远程url加载图层的 渲染方式同理, GeoJSONLayer同理 <!DOCTYPE html> <html lang"zn"><…

单片机将图片数组调出来显示MPU8_8bpp_Memory_Write

界面显示图片是很常见的需求&#xff0c;使用外挂的FLASH是最常用的方法。但是如果图片需求不大&#xff0c;比如说我们只要显示一个小图标&#xff0c;那么为了节省硬件成本&#xff0c;是不需要外挂一颗FLASH芯片的&#xff0c;我们可以将图标转成数组&#xff0c;存在单片机…

Linux八股积累与笔记

1、iptables 是一个用于配置Linux内核防火墙规则的工具。四表五链&#xff1a;在iptables中&#xff0c;有四个表&#xff08;tables&#xff09;和五个链&#xff08;chains&#xff09;&#xff0c;用于管理不同类型的数据包过滤规则。如下&#xff1a; 表&#xff08;Tabl…

51c自动驾驶~合集38

我自己的原文哦~ https://blog.51cto.com/whaosoft/12358456 #GaussianPretrain 万能3D高斯预训练表示&#xff01;爆拉3D检测、Occ、高精地图等四大任务&#xff01; 受Tesla的技术的推动&#xff0c;越来越多的厂商开始走"纯视觉"的路线&#xff0c;多数方案还…

STM32笔记(串口IAP升级)

一、IAP简介 IAP&#xff08;In Application Programming&#xff09;即在应用编程&#xff0c; IAP 是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写&#xff0c;目的是为了在产品发布后可以方便地通过预留的通信口对产 品中的固件程序进行更新升级。 通常实…