应用5:层峦叠嶂 ——布隆过滤器

新闻客户端推荐系统需实现推送去重,传统方式在用户量和新闻量庞大时性能不佳。布隆过滤器可解决此问题,能节省 90% 以上空间,有一定误判概率。介绍了 Redis 布隆过滤器的基本使用、注意事项及原理,还提及元素超出初始化大小时的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.场景:在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。新闻客户端推荐系统如何实现推送去重?

想法

(1)在服务器中记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。问题是当用户量很大,每个用户看过的新闻又很多的情况下,这种方式,推荐系统的去重工作在性能上跟的上么?

如果历史记录存储在关系数据库里,去重就需要频繁地对数据库进行exists查询,当系统并发量很高时,数据库是很难扛住压力的。

使用缓存?如此多的历史记录全部缓存起来,那得浪费多大存储空间。而且这个存储空间是随着时间线性增长,你撑得住一个月,你能撑得住几年吗?

应用:布隆过滤器。专门用来解决这种去重问题。在起到去重的同时,在空间上还能节省  90%  以上,只是稍微有那么点不精确,也就是有一定的误判概率

2.布隆过滤器是什么

        简单理解为一个不怎么精确的set 结构。使用它的contains方法判断某个对象是否存在,可能会误判。但是布隆过滤器也不是特别不精确,只要参数设置的合理,它的精确度可以控制的相对足够精确,只会有小小的误判概率。

        这里需要注意:布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在。(布隆过滤器对于已经见过的元素肯定不会误判,它只会误判那些没见过的元素

        套在上面的使用场景中,布隆过滤器能准确过滤掉那些已经看过的内容,那些没有看过的新内容,它也会过滤掉极小一部分  (误判),但是绝大多数新内容它都能准确识别。这样就可以完全保证推荐给用户的内容都是无重复的

3.redis的布隆过滤器

布隆过滤器到了Redis 4.0提供了插件功能之后才正式登场

4.基本使用

(1)bf.add添加元素,只能一次添加一个元素;bf.madd一次添加多个元素;bf.exists查询元素是否存在;bf.mexists一次查询多个元素是否存在。

127.0.0.1:6379> bf.add codehole user1

 

(integer) 1

127.0.0.1:6379> bf.add codehole user2

(integer) 1

127.0.0.1:6379> bf.exists codehole user1

(integer) 1

127.0.0.1:6379> bf.exists codehole user2

(integer) 1

127.0.0.1:6379> bf.exists codehole user3

(integer) 0

127.0.0.1:6379> bf.madd codehole user4 user5 user6

1)(integer) 1

2) (integer) 1

3) (integer) 1

127.0.0.1:6379> bf.mexists codehole user4 user5 user6 user7

1) (integer) 1

2) (integer) 1

3) (integer) 1

4) (integer) 0

(2)自定义参数的布隆过滤器

        需要我们在add 之前使用bf.reserve指令显式创建。如果对应的key 已经存在,bf.reserve会报错。bf.reserve有三个参数,分别是key, error_rate和initial_size错误率越低,需要的空间越大。initial_size参数表示预计放入的元素数量,当实际数量超出这个数值时,误判率会上升。

        需要提前设置一个较大的数值避免超出导致误判率升高。如果不使用bf.reserve,默认的error_rate是0.01,默认的 initial_size是100。

5.注意事项

initial_size估计的过大,会浪费存储空间,估计的过小,就会影响准确率,用户在使用之前一定要尽可能地精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会意外高出估计值很多

6.布隆过滤器原理

        布隆过滤器对应到Redis的数据结构里面就是一个大型的位数组几个不一样的无偏hash函数。所谓无偏就是能够把元素的has值算得比较均匀。

        向布隆过滤器中添加  key 时,会使用多个  hash 函数对  key 进行  hash  算得一个整数索引值然后对位数组长度进行取模运算得到一个位置,每个hash函数都会算得一个不同的位置。再把位数组的这几个位置都置为1就完成了add操作。

        向布隆过滤器询问  key 是否存在时,跟add一样,也会把hash的几个位置都算出来,看看位数组中这几个位置是否都位1,只要有一个位为0,那么说明布隆过滤器中这个key 不存在。如果都是1,这并不能说明这个key就一定存在,只是极有可能存在,因为这 些位被置为1可能是因为其它的key  存在所致(为什么说存在可能不存在,说不存在就一定不存在)

        使用时不要让实际元素远大于初始化大小,当实际元素开始超出初始化大小时,应该对布隆过滤器进行重建,重新分配一个  size 更大的过滤器,再将所有的历史元素批量add进去  (这就要求我们在其它的存储器中记录所有的历史元素)。因为error_rate不会因为数量超出就急剧增加,这就给我们重建过滤器提供了较为宽松的时间

以上为学习《Redis深度历险核心原理和应用实践》笔记 

内容概要:本文详细介绍了如何利用Simulink进行自动代码生成,在STM32平台上实现带57次谐波抑制功能的霍尔场定向控制(FOC)。首先,文章讲解了所需的软件环境准备,包括MATLAB/Simulink及其硬件支持包的安装。接着,阐述了构建永磁同步电机(PMSM)霍尔FOC控制模型的具体步骤,涵盖电机模型、坐标变换模块(如Clark和Park变换)、PI调节器、SVPWM模块以及用于抑制特定谐波的陷波器的设计。随后,描述了硬件目标配置、代码生成过程中的注意事项,以及生成后的C代码结构。此外,还讨论了霍尔传感器的位置估算、谐波补偿器的实现细节、ADC配置技巧、PWM死区时间和换相逻辑的优化。最后,分享了一些实用的工程集成经验,并推荐了几篇有助于深入了解相关技术和优化控制效果的研究论文。 适合人群:从事电机控制系统开发的技术人员,尤其是那些希望掌握基于Simulink的自动代码生成技术,以提高开发效率和控制精度的专业人士。 使用场景及目标:适用于需要精确控制永磁同步电机的应用场合,特别是在面对高次谐波干扰导致的电流波形失真问题时。通过采用文中提供的解决方案,可以显著改善系统的稳定性和性能,降低噪声水平,提升用户体验。 其他说明:文中不仅提供了详细的理论解释和技术指导,还包括了许多实践经验教训,如霍尔传感器处理、谐波抑制策略的选择、代码生成配置等方面的实际案例。这对于初学者来说是非常宝贵的参考资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值