缓存穿透问题及解决方案
一、什么是缓存穿透?
在分布式系统中,缓存常常用于提高系统的性能,减轻数据库的压力。缓存穿透问题指的是请求的数据在缓存和数据库中都不存在,导致请求每次都直接查询数据库,无法从缓存中获取数据,从而绕过了缓存系统,增加了数据库负载,影响系统的性能和可扩展性。
二、缓存穿透的原因
缓存穿透的原因通常有以下几个:
- 请求的数据根本不存在:比如请求了一个错误的ID,或者查询条件有误,这样查询的数据在数据库中也没有,缓存中也没有。
- 恶意请求:某些攻击者故意发送大量不合法的请求,造成缓存穿透,增加数据库压力。
三、缓存穿透的影响
缓存穿透不仅导致缓存失效,而且每次请求都需要访问数据库,这会导致以下问题:
- 增加数据库负载:大量无效请求直接访问数据库,导致数据库压力剧增,性能下降。
- 降低缓存命中率:缓存命中率降低,缓存的作用被削弱,无法有效发挥性能优势。
四、如何解决缓存穿透问题?
有几种常见的解决方法:
-
对请求进行过滤:
- 对查询条件进行校验,确保请求的数据存在,避免无效请求。
- 比如可以在后台接口中加一个数据合法性检查,避免无效请求直接查询数据库。
-
缓存空对象:
- 如果查询的数据不存在,可以将空数据缓存一段时间,这样就避免了下次再去查询数据库。
- 例如,如果请求一个用户ID不存在的用户数据,我们可以在缓存中存入一个空对象,并设置一个较短的缓存过期时间,避免恶意请求频繁访问数据库。
-
布隆过滤器:
- 布隆过滤器是一种空间效率高的数据结构,可以用来判断一个元素是否在集合中。它的主要优势在于可以在不占用太多内存的情况下高效地判断某个请求的数据是否存在。
- 在缓存穿透的情况下,可以使用布隆过滤器在请求访问数据库之前,先检查数据是否存在。如果布隆过滤器判断该数据不存在,就可以直接返回,避免访问数据库。
五、Java案例:如何使用布隆过滤器解决缓存穿透问题
在这个示例中,我们将使用Guava库来实现布隆过滤器,解决缓存穿透问题。首先,假设我们有一个查询用户信息的接口,系统通过缓存存储用户信息,如果缓存中没有,查询数据库,如果数据库也没有,直接返回空。我们通过布隆过滤器来防止无效请求访问数据库。
步骤:
- 使用布隆过滤器判断用户ID是否存在。
- 如果ID不存在,直接返回。
- 如果ID存在,则查询缓存,如果缓存没有,查询数据库,并将结果存入缓存。
Java代码示例:
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;public class CachePenetrationExample {// 模拟的数据库查询方法public String getUserFromDatabase(String userId) {// 模拟数据库查询,假设ID为"100"的数据存在,其他都不存在if ("100".equals(userId)) {return "User Data for ID " + userId;} else {return null;}}// 创建一个布隆过滤器,用于判断用户ID是否存在private BloomFilter<String> userIdBloomFilter = BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF_8), 1000000, 0.01); // 100万元素,假设误判率为1%// 模拟的缓存类private Cache<String, String> cache = new Cache<>();public String getUser(String userId) {// 先用布隆过滤器判断用户ID是否存在if (!userIdBloomFilter.mightContain(userId)) {// 如果布隆过滤器判断该ID不存在,直接返回空,避免查询数据库return null;}// 缓存中查找数据String userData = cache.get(userId);if (userData != null) {return userData; // 如果缓存命中,直接返回}// 缓存没有命中,查询数据库userData = getUserFromDatabase(userId);if (userData != null) {// 如果数据库中有,放入缓存cache.put(userId, userData);} else {// 如果数据库中没有,缓存空数据,避免后续穿透cache.put(userId, ""); // 存入空数据,避免频繁访问数据库}return userData;}// 模拟缓存类(简单示例,实际应用中可以使用如Guava Cache等成熟库)static class Cache<K, V> {private final java.util.Map<K, V> cache = new java.util.HashMap<>();public V get(K key) {return cache.get(key);}public void put(K key, V value) {cache.put(key, value);}}public static void main(String[] args) {CachePenetrationExample example = new CachePenetrationExample();// 初始化布隆过滤器,预先假设一些用户ID存在example.userIdBloomFilter.put("100");// 模拟查询不同用户IDSystem.out.println(example.getUser("100")); // 从数据库查询,缓存并返回System.out.println(example.getUser("101")); // 返回null,避免查询数据库System.out.println(example.getUser("100")); // 从缓存中直接返回System.out.println(example.getUser("102")); // 返回null,避免查询数据库}
}
六、代码说明
-
布隆过滤器:通过Guava的
BloomFilter
创建了一个布隆过滤器来判断用户ID是否存在。如果布隆过滤器认为ID不存在,我们直接返回空结果,避免访问数据库。 -
缓存实现:简单使用了一个
Cache
类来模拟缓存。实际项目中可以使用如Guava Cache或者其他缓存库。 -
查询逻辑:
- 首先通过布隆过滤器检查数据是否存在。
- 然后尝试从缓存中获取数据。
- 如果缓存中没有,再查询数据库,并将结果缓存。
- 如果数据库没有数据,则缓存空对象,避免后续请求再去查询数据库。
七、总结
缓存穿透是一个常见的性能问题,尤其是在高并发系统中。通过布隆过滤器,我们能够在访问数据库之前,快速判断某个请求是否有效,从而有效地避免了缓存穿透的发生,减轻了数据库压力,提升了系统性能。
解决方案的关键要点:
- 布隆过滤器可以有效地判断请求数据是否存在,避免无效请求访问数据库。
- 缓存空对象可以避免频繁访问数据库,减少数据库压力。
如果系统中有大量无效请求,布隆过滤器是非常有效的解决方案。
相关文章:
缓存穿透问题及解决方案
一、什么是缓存穿透? 在分布式系统中,缓存常常用于提高系统的性能,减轻数据库的压力。缓存穿透问题指的是请求的数据在缓存和数据库中都不存在,导致请求每次都直接查询数据库,无法从缓存中获取数据,从而绕…...
ElementUI el-popover弹框背景色设置
1.el-popover样式由于使用了 absolute 属性,导致脱离了节点,所以在父级元素使用class无法进行权重处理来修改其样式,解决方式如下:通过popper-class实现样式处理,避免全局样式污染 // html <el-popoverplacement&q…...
在 Mac ARM 架构上使用 nvm 安装 Node.js 版本 16.20.2
文章目录 1. 安装 nvm(如果还没有安装的话)2. 加载 nvm 配置3. 列出特定系列的 Node.js 版本(远程):4. 安装 Node.js 16.20.25. 使用指定版本的 Node.js6. 验证安装 在 Mac ARM 架构上使用 nvm 安装 Node.js 版本 16.…...
spring集成activiti流程引擎(源码)
前言 activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,请假审批demo从流程绘制到审批结束实例。 源码获取:本文末个人名片直接获取。 一、项目形式 springbootvueactiviti集成了activiti在线编辑器,流行…...
VLLM历次会议(2024.4)
Prefix Caching。预先算好KV cache,遇见公共前缀,复用之,避免再计算一遍。 场景:1. 多轮对话。2.公共的system prompt。 Guided Decoding(格式化输出) 通过Outlines工具实现。 支持正则表达式、JSON格式等。 输入:…...
基于 Docker 搭建 Elasticsearch + Kibana 环境
一、Elasticsearch 1. 下载镜像 elasticsearch镜像不支持latest标签,必须指定版本号 % docker pull elasticsearch:8.17.2 2. 启动容器 参考官方文档 https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docker.html % docker run -p 9200:9200 -p 9…...
在 ARM64 架构系统离线安装 Oracle Java 8 全流程指南
在 ARM64 架构系统离线安装 Oracle Java 8 全流程指南 文章目录 在 ARM64 架构系统离线安装 Oracle Java 8 全流程指南一、引言二、下载前的准备2.1 确认系统架构2.2 注册 Oracle 账号 三、从 Oracle 官方下载 Java 8 for ARM643.1 访问 Oracle Java 存档页面3.2 选择合适的版本…...
策略模式-小结
总结一下看到的策略模式: A:一个含有一个方法的接口 B:具体的实行方式行为1,2,3,实现上面的接口。 C:一个环境类(或者上下文类),形式可以是:工厂模式,构造器注入模式,枚举模式。 …...
记一次Self XSS+CSRF组合利用
视频教程在我主页简介或专栏里 (不懂都可以来问我 专栏找我哦) 目录: 确认 XSS 漏洞 确认 CSRF 漏洞 这个漏洞是我在应用程序的订阅表单中发现的一个 XSS 漏洞,只能通过 POST 请求进行利用。通常情况下,基于 POST 的…...
VSCode + Continue 实现AI编程助理
安装VS Code 直接官网下载安装,反正是免费的。 安装VS插件Continue 直接在插件市场中搜索, Continue,第一个就是了。 配置Chat Model 点击Add Chat model后进行选择: 选择Ollama后,需要点击下面的config file : 由于…...
使用Typescript开发Babylon.js的Vue3模板参考
main.js文件 // main.ts import { createApp } from vue import App from ./App.vuecreateApp(App).mount(#app) App.vue文件 <!-- App.vue --> <template><div class"app-container"><BabylonScene /></div> </template><…...
STM32+Proteus+DS18B20数码管仿真实验
1. 实验准备 硬件方面: 了解 STM32 单片机的基本原理和使用方法,本实验可选用常见的 STM32F103 系列。熟悉 DS18B20 温度传感器的工作原理和通信协议(单总线协议)。数码管可选用共阴极或共阳极数码管,用于显示温度值。…...
DeepSeek自然语言处理(NLP)基础与实践
自然语言处理(Natural Language Processing, NLP)是人工智能领域的一个重要分支,专注于让计算机理解、生成和处理人类语言。NLP技术广泛应用于机器翻译、情感分析、文本分类、问答系统等场景。DeepSeek提供了强大的工具和API,帮助我们高效地构建和训练NLP模型。本文将详细介…...
Baklib优化数字化内容管理用科技提升商业效率与增值潜力
内容概要 在当今数字化迅速发展的时代,数字化内容管理已成为企业提升竞争力的重要手段。Baklib作为一款强大的智能优化内容管理系统,通过先进的科技手段,帮助企业在内容管理和数据整合方面实现高效运作。Baklib 是什么类型的工具,…...
视频基础操作
1.1. 例子 读取mp4格式的视频,将每一帧改为灰度图,并且打上水印(“WaterMark”),并将其输出保存为out.mp4,在这个例子中可以看到视频读取,每帧数据处理,视频保存的整体流程简单示例 import cv…...
写一个鼠标拖尾特效
思路和逻辑 要实现鼠标拖尾特效,我们需要: 监听鼠标移动事件,获取鼠标的当前位置。在每次鼠标移动时,绘制一个小圆点或其他形状在鼠标的当前位置。将所有绘制的圆点连接起来,形成一条“尾巴”。使用动画效果让尾巴看…...
Docker上安装Zabbix-server-mysql报错
创建新的zabbix server (mysql)容易,最后一条日志报错 cannot usedatabase"zabbix": its "users" table is empty (is this the Zabbix proxy database?) 往前还有一条关键报错信息 ERROR 1153 (08S01): Got a packe…...
<tauri><rust><GUI>使用tauri创建一个图片浏览器(文件夹遍历、图片切换)
前言 本文是基于rust和tauri,由于tauri是前、后端结合的GUI框架,既可以直接生成包含前端代码的文件,也可以在已有的前端项目上集成tauri框架,将前端页面化为桌面GUI。 环境配置 系统:windows 10平台:visual studio code语言:rust、javascript库:tauri2.0概述 本文是…...
【STM32系列】利用MATLAB配合ARM-DSP库设计IIR数字滤波器(保姆级教程)
ps.源码放在最后面 设计FIR数字滤波器可以看这里:利用MATLAB配合ARM-DSP库设计FIR数字滤波器(保姆级教程) 设计IIR滤波器 MATLAB配置 设计步骤 首先在命令行窗口输入"filterDesigner",接着就会跳出以下界面…...
迷宫(信息学奥赛一本通-1215)
【题目描述】 一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由nn的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或…...
centos7 curl#6 - Could not resolve host mirrorlist.centos.org; 未知的错误 解决方案
问题描述 centos7系统安装完成后,yum安装软件时报错“curl#6 - “Could not resolve host: mirrorlist.centos.org; 未知的错误”” [root192 ~]# yum install vim -y 已加载插件:fastestmirror Determining fastest mirrors Could not retrieve mirro…...
Ubuntu安装PgSQL17
参考官网教程,Ubuntu24 apt在线安装Postgres 17 1. 要手动配置 Apt 存储库 # 导入存储库签名密钥: sudo apt install curl ca-certificates sudo install -d /usr/share/postgresql-common/pgdg sudo curl -o /usr/share/postgresql-common/pgdg/apt…...
在 Navicat 17 中扩展 PostgreSQL 数据类型 - 范围类型
范围类型 PostgreSQL 是市场上最灵活的数据库之一,这已不是什么秘密。事实上,PostgreSQL 的可扩展性和丰富的功能集使 PostgreSQL 近期已超越 MySQL,成为最受开发人员推崇和最受欢迎的数据库系统。在这个使用 Navicat Premium 17 在 Postgre…...
VMware Workstate 的 Ubuntu18 安装 vmware tools(不安装没法共享)
在共享主机路径后,可以在: /mnt/hgfs/下方找到共享的文件。但没有安装vmware tool时是没法共享的。 如何安装vmware tool,网上版本很多。这里记录一下: VMware Workstation 17 Pro,版本:17.6.0 虚拟机系统…...
稀土抑烟剂——为汽车火灾安全增添防线
一、稀土抑烟剂的基本概念 稀土抑烟剂是一类基于稀土元素(如稀土氧化物和稀土金属化合物)开发的高效阻燃材料。它可以显著提高汽车内饰材料的阻燃性能,减少火灾发生时有毒气体和烟雾的产生。稀土抑烟剂不仅能提升火灾时的安全性,…...
【工业安全】-CVE-2019-17621-D-Link Dir-859L 路由器远程代码执行漏洞
文章目录 1.漏洞描述 2.环境搭建 3.漏洞复现 4.漏洞分析 4.1:代码分析 4.2:流量分析 5.poc代码: 1.漏洞描述 漏洞编号:CVE-2019-17621 漏洞名称:D-Link DIR-859 命令注入漏洞 威胁等级:严重 漏洞详…...
git 记录
git 记录 报错warning: unknown value given to http.version: 2 报错 warning: unknown value given to http.version: ‘2’ 删除指定http版本 git config --global --unset http.version...
MVC(Model-View-Controller)framework using Python ,Tkinter and SQLite
1.项目结构 sql: CREATE TABLE IF NOT EXISTS School (SchoolId TEXT not null, SchoolName TEXT NOT NULL,SchoolTelNo TEXT NOT NULL) 整体思路 Model:负责与 SQLite 数据库进行交互,包括创建表、插入、删除、更新和查询数据等操作。View࿱…...
算法——数学建模中的“上帝掷骰子”:蒙特卡罗算法
一、从原子弹到《原神》:随机算法的封神之路 1946年洛斯阿拉莫斯实验室,冯诺伊曼团队用掷骰子的方式,成功预测了氢弹的中子扩散——这是蒙特卡罗算法首次震惊世界。 2023年《原神》物理引擎,角色技能特效的光线追踪计算ÿ…...
洗牌加速!车规MCU“冷热交加”
汽车芯片赛道,正在经历新一轮震荡期。 本周,全球汽车芯片巨头—NXP对外披露了不及资本市场预期的四季度的财报,营收同比下降9%,全年下降5%,表明工业和汽车市场需求的低迷仍在持续。 公开信息显示,该公司一…...
面试整理-Java中常见创建线程池的方法
使用 Executors 工具类 Executors.newFixedThreadPool(int nThreads) 特点:创建一个固定大小的线程池,线程池中的线程数始终保持不变。 适用场景:适用于任务量已知且相对固定的场景,可以有效控制资源的使用。…...
计算机毕业设计——springboot教师人事档案管理系统
📘 博主小档案: 花花,一名来自世界500强的资深程序猿,毕业于国内知名985高校。 🔧 技术专长: 花花在深度学习任务中展现出卓越的能力,包括但不限于java、python等技术。近年来,花花更…...
ASP.NET Core程序的部署
发布 不能直接把bin/Debug部署到生产环境的服务器上,性能低。应该创建网站的发布版,用【发布】功能。两种部署模式:“框架依赖”和“独立”。独立模式选择目标操作系统和CPU类型。Windows、Linux、iOS;关于龙芯。 网站的运行 在…...
Python练习11-20
题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 题目:判断101-200之间有多少…...
【Android开发AI实战】选择目标跟踪基于opencv实现——运动跟踪
文章目录 【Android 开发 AI 实战】选择目标跟踪基于 opencv 实现 —— 运动跟踪一、引言二、Android 开发与 AI 的融合趋势三、OpenCV 简介四、运动跟踪原理(一)光流法(二)卡尔曼滤波(三)粒子滤波 五、基于…...
深入浅出:Python 中的异步编程与协程
引言 大家好,今天我们来聊聊 异步编程 和 协程,这是近年来编程语言领域中的热点话题之一,尤其在 Python 中,它作为一种全新的编程模型,已经成为处理 IO密集型 任务的强力工具。尽管很多人对异步编程望而却步࿰…...
iOS Swift算法之KDF2
后端用Java开发的,用到了org.bouncycastle.crypto.generators.KDF2BytesGenerator,一开始在网上各种搜,没找到相关的接口或第三方库,白白浪费了几天时间,后面才想到照着Java代码自己实现,于是乎参考BaseKDF…...
PyQt6/PySide6 QImage 类
PyQt6/PySide6 QImage 类详解 一、QImage 概述 QImage 是 Qt 框架中用于处理图像数据的核心类,提供: 独立于硬件的图像表示像素级访问和操作多种图像格式支持(PNG/JPEG/BMP等)图像转换和基本处理功能 from PyQt6.QtGui import…...
Java8新特性Optional,Function,Supplier,Consumer
Java8新特性 1.Optional 首先,Optional 它不是一个函数式接口,设计它的目的是为了防止空指针异常(NullPointerException),要知道在 Java 编程中, 空指针异常可是臭名昭著的。 让我们来快速了解一下 Opti…...
腾讯云服务器中Ubuntu18.04搭建python3.7.0与TensorFlow1.15.0与R-4.0.3环境
所有踩过的坑,都化成了这条平坦的路 云服务器配置 基础配置选择竞价实例(便宜/需求小) 选择地区(距离自己近的就行) 实例配置选择异构计算(能力较强,性价比高)根据GPU显存需求选择…...
01.Docker 概述
Docker 概述 1. Docker 的主要目标2. 使用Docker 容器化封装应用程序的意义3. 容器和虚拟机技术比较4. 容器和虚拟机表现比较5. Docker 的组成6. Namespace7. Control groups8. 容器管理工具9. docker 的优缺点10. 容器的相关技术 docker 官网: http://www.docker.com 帮助文档…...
DedeBIZ系统审计小结
之前简单审计过DedeBIZ系统,网上还没有对这个系统的漏洞有过详尽的分析,于是重新审计并总结文章,记录下自己审计的过程。 https://github.com/DedeBIZ/DedeV6/archive/refs/tags/6.2.10.zip 📌DedeBIZ 系统并非基于 MVC 框架&…...
docker运行perplexica
序 本文主要研究一下如何用docker运行perplexica 步骤 git clone git clone https://github.com/ItzCrazyKns/Perplexica.gitapp.dockerfile FROM docker.1ms.run/node:20.18.0-alpineARG NEXT_PUBLIC_WS_URLws://127.0.0.1:3001 ARG NEXT_PUBLIC_API_URLhttp://127.0.0.1…...
【ThreeJS Basics 1-3】Hello ThreeJS,实现第一个场景
文章目录 环境创建一个项目安装依赖基础 Web 页面概念解释编写代码运行项目 环境 我的环境是 node version 22 创建一个项目 首先,新建一个空的文件夹,然后 npm init -y , 此时会快速生成好默认的 package.json 安装依赖 在新建的项目下用 npm 安装依…...
解决珠玑妙算游戏问题:C 语言实现
一、引言 珠玑妙算游戏(the game of master mind)是一个有趣的逻辑推理游戏。在编程领域,我们可以通过编写代码来模拟游戏中计算猜中与伪猜中次数的过程。本文将详细介绍如何使用 C 语言实现这一功能,并对核心代码进行解析。 二、…...
【清晰教程】本地部署DeepSeek-r1模型
【清晰教程】通过Docker为本地DeepSeek-r1部署WebUI界面-CSDN博客 目录 Ollama 安装Ollama DeepSeek-r1模型 安装DeepSeek-r1模型 Ollama Ollama 是一个开源工具,专注于简化大型语言模型(LLMs)的本地部署和管理。它允许用户在本地计算机…...
Java/Kotlin 使用 Chrome 无头浏览器
1. 概念 无头浏览器在类似于流行网络浏览器的环境中提供对网页的自动控制,但是通过命令行界面或使用网络通信来执行。 它们对于测试网页特别有用,因为它们能够像浏览器一样呈现和理解超文本标记语言,包括页面布局、颜色、字体选择以及JavaSc…...
AI前端开发:赋能开发者,提升解决实际问题的能力
近年来,人工智能技术飞速发展,深刻地改变着各行各业。在软件开发领域,AI写代码工具的出现更是引发了一场革命,尤其是前端开发领域,AI的应用正在显著提升开发者的解决实际问题的能力。本文将探讨AI前端开发如何提升效率…...
【Elasticsearch】Elasticsearch检索方式全解析:从基础到实战(二)
接着上一篇文章;我们继续来研究es的复杂检索 文章目录 (1) bool用来做复合查询(2)Filter【结果过滤】(3)term(4)Aggregation(执行聚合) (1) bool用来做复合查询 复合语…...
ASP.NET Core SignalR的分布式部署
假设聊天室程序被部署在两台服务器上,客户端1、2连接到了服务器A上的ChatRoomHub,客户端3、4连接到服务器B上的ChatRoomHub,那么客户端1发送群聊消息时,只有客户端1、2能够收到,客户端3、4收不到;在客户端3…...