面试redis主题一“什么是缓存穿透”

news/2024/10/21 3:20:54/

条件

缓存穿透是因为查询redis时发现其中没有要查询的数据,大量请求DB导致DB压力过大崩溃。这种情况大部分是因为恶意攻击。

解决方法

使用布隆过滤器

它是一种基于概率的数据结构,主要用来判断某个元素是否在集合内,它具有运行速度快(时间效率),占用内存小的优点(空间效率),但是有一定的误识别率和删除困难的问题。它能够告诉你某个元素一定不在集合内可能在集合内

原理总结


1.一个很长的二进制数组 (位数组,就是这个数组里只有0和1)
2.若干个哈希函数
3.空间效率和查询效率高
4.不存在漏报(False Negative),即某个元素在某个集合中,肯定能报出来。
5.可能存在误报(False Positive),即某个元素不在某个集合中,可能也被爆出来。
5.删除困难

代码实现布隆过滤器

public class SimpleBloomFilter {private static final int DEFAULT_SIZE = 2 << 24;    // 布隆过滤器的比特长度private static final int[] seeds = new int[] {7, 11, 13, 31,37, 61};    // 这里要选取质数,能很好的降低错误率private BitSet bits = new BitSet(DEFAULT_SIZE);private SimpleHash[] func = new SimpleHash[seeds.length];public static void main(String[] args) {String value = "crankzcool@gmail.com";SimpleBloomFilter filter = new SimpleBloomFilter();System.out.println(filter.contains(value));filter.add(value);System.out.println(filter.contains(value));}public SimpleBloomFilter() {for (int i = 0; i < seeds.length; i++) {func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);}}public void add(String value) {for (SimpleHash f: func) {bits.set(f.hash(value), true);}}public boolean contains(String value) {if (value == null) {return false;}boolean ret = true;for (SimpleHash f : func) {ret = ret && bits.get(f.hash(value));}return ret;}public static class SimpleHash {private int cap;private int seed;public SimpleHash(int cap, int seed) {this.cap = cap;this.seed = seed;}public int hash(String value) {int result = 0;int len = value.length();for (int i = 0; i < len; i++) {result = seed * result + value.charAt(i);}return (cap - 1) & result;}}

pom引入依赖实现布隆过滤器

pom依赖


<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>27.0.1-jre</version>
</dependency>

 代码实现

public static void main(String[] args) {// 1.创建符合条件的布隆过滤器// 预期数据量10000,错误率0.0001BloomFilter<CharSequence> bloomFilter =BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")),10000, 0.0001);// 2.将一部分数据添加进去for (int i = 0; i < 5000; i++) {bloomFilter.put("" + i);}System.out.println("数据写入完毕");// 3.测试结果for (int i = 0; i < 10000; i++) {if (bloomFilter.mightContain("" + i)) {System.out.println(i + "存在");} else {System.out.println(i + "不存在");}}
}


 


http://www.ppmy.cn/news/1116533.html

相关文章

java集合 list转map一些常用的方式(Stream流,,,)

Java 集合之间的转换 java集合 list转map一些常用的方式&#xff08;Stream流&#xff0c;&#xff0c;&#xff0c;&#xff09; 提示&#xff1a;帮助文档 文章目录 Java 集合之间的转换前言一、List转换为Map&#xff1f;1.1、**List**<**Object**>**转化为Map<Int…

Android13适配-Google官方照片视频选择器

官方照片选择器 图 1. 照片选择器提供了一个直观的界面&#xff0c;便于与您的应用分享照片。 照片选择器的界面可供浏览和搜索&#xff0c;并按日期降序向用户显示其媒体库中的文件。如隐私保护最佳实践 Codelab 中所示&#xff0c;照片选择器为用户提供了一种安全的内置授权…

go语言---锁

什么是锁呢&#xff1f;就是某个协程&#xff08;线程&#xff09;在访问某个资源时先锁住&#xff0c;防止其它协程的访问&#xff0c;等访问完毕解锁后其他协程再来加锁进行访问。这和我们生活中加锁使用公共资源相似&#xff0c;例如&#xff1a;公共卫生间。 死锁 死锁是…

docker 已经配置了国内镜像源,但是拉取镜像速度还是很慢(gcr.io、quay.io、ghcr.io)

前言 国内用户在使用 docker 时&#xff0c;想必都遇到过镜像拉取慢的问题&#xff0c;那是因为 docker 默认指向的镜像下载地址是 https://hub.docker.com&#xff0c;服务器在国外。 网上有关配置 docker 国内镜像源的教程很多&#xff0c;像 腾讯、阿里、网易 等等都会提供…

数据分析三剑客之一:Pandas详解

目录 1 Pandas介绍 2 Pandas的安装与导入 2.1 Pandas模块安装 2.2 Pandas模块导入 3 pandas数据结构及函数 3.1 Series结构 3.1.1 ndarray创建Series对象 3.1.2 dict创建Series对象 3.1.3 标量创建Series对象 3.1.4 位置索引访问Series数据 3.1.5 标签索引访问Series…

2023年以就业为目的学习Java还有必要吗?(文末送书)

目录 一、活力四射的 Java二、从零开始学会 Java三、准备工作四、基础知识五、进阶知识六、高级知识七、结语参与方式 大家好&#xff0c;我是哪吒。 文末送5本《Java编程动手学》 今天来探讨一个问题&#xff0c;现在学 Java 找工作还有优势吗&#xff1f; 在某乎上可以看到…

PowerDesigner数据库设计

PowerDesigner数据库设计_迷茫的启明星的博客-CSDN博客

elasticsearch bulk 批量操作

1&#xff1a;bulk 是 elasticsearch 提供的一种批量增删改的操作API bulk 对 JSON串 有着严格的要求。每个JSON串 不能换行 &#xff0c;只能放在同一行&#xff0c;同时&#xff0c; 相邻的JSON串之间必须要有换行 &#xff08;Linux下是\n&#xff1b;Window下是\r\n&#…