YimMenu使用指南:从入门到精通的GTA5辅助工具实践手册

核心内容摘要

AI赋能教学创新应该怎么做?这些优秀案例值得借鉴!
AI语音创作新选择:Qwen3-TTS模型功能全面测评

非洲经济学子强化计算技能

Redis 缓存主要缓存穿透、缓存击穿与缓存雪崩异常场景今天我们来讲讲缓存穿透。

1 场景描述缓存穿透是指客户端请求一个缓存和数据库中都不存在的 key。

由于缓存中不存在所以请求会透过缓存查询数据库由于数据库中也不存在所以也没办法更新缓存。

因此下一次同样的请求还是会打在数据库上。

好像缓存被穿透了一样缓存形如虚设。

所有的压力都在数据库之上如果请求量巨大可能造成数据库崩溃。

2 解决方法缓存穿透有以下几种解决方法。

1 接口校验在请求入口进行校验比如对用户进行鉴权、数据合法性检查等操作这样可以减少缓存穿透发生的概率。

这种方式减轻了对 Redis 以及数据库的压力但是增加了客户端的编码与维护的工作量。

如果请求的入口很多那么工作量很大。

2 缓存空值当缓存与数据库中都没有 key 时就设置一个空值写入缓存并同时设置一个比较短的过期时间。

由于在缓存中设置空值所以请求在缓存这一级别就返回也就不会被穿透。

这些所说的不会被穿透只是针对某个 key 而言的。

其它没有设置空值的 key仍然存在被穿透的可能。

该方法的问题是由于不存在的 key 几乎是无限不可被穷举的所以不可能都设置到缓存中。

而且大量这样的空值 key 设置到缓存也会占用大量的内存空间。

解决采用下面提到的布隆过滤器直接过滤掉不存在的 key。

3 布隆过滤器布隆过滤器Bloom Filter是1970年由布隆提出的。

它实际上是一个很长的二进制向量和一系列随机映射函数。

布隆过滤器可以用于判断一个元素是否在一个集合中2。

布隆过滤器的特点是判断为不存在的则一定不存在判断存在的则大概率存在。

2.

1 布隆过滤器原理布隆过滤器的原理是当一个元素被加入集合时通过K个散列函数将这个元素映射成一个位数组中的K个点把它们置为1。

检索时我们只要看看这些点是不是都是1就大约知道集合中有没有它了如果这些点有任何一个0则被检元素一定不在如果都是1则被检元素很可能在。

这就是布隆过滤器的基本思想3。

假设有这样一个集合 S它包含 a b c 三个元素。

那么布隆过滤器会利用多个哈希函数图中是三个哈希函数 h

h

h3来计算所在的位然后将该位设置为 1。

比如元素 a经过三个哈希函数计算后将相应的位设置为 1也就是图中的红线。

元素 b 和 c 也是按照相应的方法进行计算处理。

这时布隆过滤器初始化完毕。

假设有一个元素 d需要判断它是否在我们刚才所创建的布隆过滤器中图中的黄色线条。

经过三个哈希函数 h

h

h3 计算后发现相应的位都是 1布隆过滤器会返回 true。

也就是认为这个元素可能在也可能不在集合中。

看到这里有同学就会问“既然这个布隆过滤器都不知道这个元素是不是在集合中对我们有什么用呢”布隆过滤器的强大之处是可以利用较小的缓存就可以判断出某个元素是否不在集合中。

比如又来了一个元素 e经过三个哈希函数 h

h

h3 计算后发现 h1(e) 所对应的位是 0。

那么这个元素 e 肯定不在集合中。

有同学又说了“我用 HashMap 不是也能判断出某个元素在不在集合中呀”HashMap 是可以判断但需要存储集合中所有的元素。

如果集合中有上亿个元素那么就会占用大量的内存。

内存空间毕竟是有限可能还不一定放的下这么多的元素。

与HashMap相比 布隆过滤器占用的空间很小所以很适合判断大集合中某个元素是否不存在。

2.

2 布隆过滤器误识别率之前的示例中可以看出布隆过滤器判断为不存在的元素则一定不存在而判断存在的元素则大概率存在。

也就是说有的元素可能并不在集合中但是布隆过滤器会认为它存在。

这就涉及到一个概念误识别率。

误识别率指的错误判断一个元素在集合中的概率。

假设布隆过滤器有 m bit 大小需要放入 n 个元素每个元素使用 k 个哈希函数那么它的误识别率如下表所示4。

2.

3 使用布隆过滤器Google 的 Guava 库提供了使用布隆过滤器的 API 类BloomFilter.class它是线程安全的。

首先创建布隆过滤器//创建存储整型的布隆过滤器 bloomFilter BloomFilter.create(Funnels.integerFunnel(), expectedInsertions, fpp);创建布隆过滤器的方法有以下几个入参入参说明Funnels 实例用于后续把类对象转换为相应的 hash 值。

expectedInsertions期望插入过滤器的元素个数。

fpp误识别率该值必须大于 0 且小于

0。

Funnel 类定义了如何把一个具体的对象类型分解为原生字段值从而将值分解为 Byte 以供后面 BloomFilter 进行 hash 运算5。

也就是说 Guava 的布隆过滤器会根据Funnel 类的定义计算一个对象的哈希值放入过滤器。

Guava 官方提供了这样一个创建可插入自定义类的布隆过滤器示例。

首先创建一个 Person 类Data AllArgsConstructor public class Person { private String firstName; private String lastName; private int age; }然后创建一个 PersonFunnel 类它实现了 Funnel 类中的 funnel(Person from, PrimitiveSink into) 方法public class PersonFunnel implements FunnelPerson { Override public void funnel(Person from, PrimitiveSink into) { into.putUnencodedChars(from.getFirstName()).putUnencodedChars(from.getLastName()).putInt(from.getAge()); } }这个方法主要是把 Person 类中的各个属性名字、年龄写入 PrimitiveSink 对象。

PrimitiveSink 提供了支持各种写入类型的方法接着把元素放入布隆过滤器bloomFilter.put(new Person(deniro,lee,

); bloomFilter.put(new Person(lily,lee,

);最后就是判断某个元素是否在布隆过滤器中Assert.assertFalse(bloomFilter.mightContain(new Person(jack,lee,

)); Assert.assertTrue(bloomFilter.mightContain(new Person(deniro,lee,

));Funnels 是个工具类内置了一些创建基本类型的 Funnel我们可以利用这些 Funnel来创建包含基本类型元素的布隆过滤器比如创建一个包含整型元素的布隆过滤器BloomFilterInteger bloomFilter BloomFilter.create(Funnels.integerFunnel(), size, fpp);最后让我们

总结一波。

可以看到接口校验方法与 Guava 版的布隆过滤器方法都是在客户侧进行处理。

布隆过滤器也可以在缓存层进行处理。

相对来说布隆过滤器方法比接口校验方法少了很多代码量与维护成本。

缓存空值不可取毕竟内存空间是有限的。

利用布隆过滤器我们可以拦截绝大多数不存在的 key因此很适合解决 Redis 缓存穿透问题。

AI大模型学习福利作为一名热心肠的互联网老兵我决定把宝贵的AI知识分享给大家。

至于能学习到多少就看你的学习毅力和能力了 。

我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

全套AGI大模型学习路线AI大模型时代的学习之旅从基础到前沿掌握人工智能的核心技能因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获取

640套AI大模型报告合集这套包含640份报告的合集涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。

无论您是科研人员、工程师还是对AI大模型感兴趣的爱好者这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获

AI大模型经典PDF籍随着人工智能技术的飞速发展AI大模型已经成为了当今科技领域的一大热点。

这些大型预训练模型如GPT-

BERT、XLNet等以其强大的语言理解和生成能力正在改变我们对人工智能的认识。

那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获

AI大模型商业化落地方案因篇幅有限仅展示部分资料需要点击文章最下方名片即可前往获作为普通人入局大模型时代需要持续学习和实践不断提高自己的技能和认知水平同时也需要有责任感和伦理意识为人工智能的健康发展贡献力量

17分钟真人录音mp3百度云网盘-17分钟真人录音mp3百度云网盘应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123