redis高级数据结构布隆过滤器
文章目录
- 背景
- 什么是布隆过滤器
- Redis 中的布隆过滤器
- 布隆过滤器使用
- 注意事项
- 实现原理
- 空间占用估计
背景
我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的?
你会想到服务器记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。问题是当用户量很大,每个用户看过的新闻又很多的情况下,这种方式,推荐系统的去重工作在性能上跟的上么?
实际上,如果历史记录存储在关系数据库里,去重就需要频繁地对数据库进行 exists 查询,当系统并发量很高时,数据库是很难扛住压力的。你可能又想到了缓存,但是如此多的历史记录全部缓存起来,那得浪费多大存储空间啊?而且这个存储空间是随着时间线性增长,你撑得住一个月,你能撑得住几年么?但是不缓存的话,性能又跟不上,这该怎么办?这时,布隆过滤器 (Bloom Filter) 闪亮登场了,它就是专门用来解决这种去重问题的。它在起到去重的同时,在空间上还能节省 90% 以上,只是稍微有那么点不精确,也就是有一定的误判概率。
什么是布隆过滤器
布隆过滤器可以理解为一个不怎么精确的 set 结构,当你使用它的 contains 方法判断某个对象是否存在时,它可能会误判。但是布隆过滤器也不是特别不精确,只要参数设置的合理,它的精确度可以控制的相对足够精确,只会有小小的误判概率。
当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存
在。这来源于它的底层实现,在接下来讲解原理时你就明白了。
Redis 中的布隆过滤器
Redis 官方提供的布隆过滤器到了 Redis 4.0 提供了插件功能之后才正式登场。布隆过滤器作为一个插件加载到 Redis Server 中,给 Redis 提供了强大的布隆去重功能。
布隆过滤器使用
布隆过滤器有二个基本指令, bf.add 添加元素, bf.exists 查询元素是否存在,它的用法和 set 集合的 sadd 和 sismember 差不多。注意 bf.add 只能一次添加一个元素,如果想要一次添加多个,就需要用到 bf.madd 指令。同样如果需要一次查询多个元素是否存在,就需要用到 bf.mexists 指令。
注意事项
创建布隆过滤器时需要3个参数,分别是 key, error_rate 和 initial_size。错误率越低,需要的空间越大。 initial_size 参数表示预计放入的元素数量,当实际数量超出这个数值时,误判率会上升。
所以需要提前设置一个较大的数值避免超出导致误判率升高。如果不使用 bf.reserve,默认的 error_rate 是 0.01,默认的 initial_size 是 100。
布隆过滤器的 initial_size 估计的过大,会浪费存储空间,估计的过小,就会影响准确
率,用户在使用之前一定要尽可能地精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会意外高出估计值很多。
布隆过滤器的 error_rate 越小,需要的存储空间就越大,对于不需要过于精确的场合,error_rate 设置稍大一点也无伤大雅。比如在新闻去重上而言,误判率高一点只会让小部分文章不能让合适的人看到,文章的整体阅读量不会因为这点误判率就带来巨大的改变。
实现原理
如下是一张布隆过滤器的结构图:

每个布隆过滤器对应到 Redis 的数据结构里面就是一个大型的位数组和几个不一样的无偏 hash 函数。所谓无偏就是能够把元素的 hash 值算得比较均匀。
向布隆过滤器中添加 key 时,会使用多个 hash 函数对 key 进行 hash 运算得一个整数索引值然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为 1 就完成了 add 操作。
向布隆过滤器询问 key 是否存在时,跟 add 一样,也会把 hash 的几个位置都算出
来,看看位数组中这几个位置是否都位 1,只要有一个位为 0,那么说明布隆过滤器中这个key 不存在。如果都是 1,这并不能说明这个 key 就一定存在,只是极有可能存在,因为这些位被置为 1 可能是因为其它的 key 存在所致。如果这个位数组比较小,这个概率就会很大,如果这个位数组比较大,这个概率就会降低。
使用时不要让实际元素远大于初始化大小,当实际元素开始超出初始化大小时,应该对布隆过滤器进行重建,重新分配一个 size 更大的过滤器,再将所有的历史元素批量 add 进去 (这就要求我们在其它的存储器中记录所有的历史元素)。因为 error_rate 不会因为数量超出就急剧增加,这就给我们重建过滤器提供了较为宽松的时间。
空间占用估计
有很多现成的网站已经支持计算空间占用的功能了,我们只要把参数输进去,就可以直接看到结果。
相关文章:
redis高级数据结构布隆过滤器
文章目录 背景什么是布隆过滤器Redis 中的布隆过滤器布隆过滤器使用注意事项实现原理空间占用估计 背景 我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。问题来了,新闻…...
mysql 5.7安装
基础环境:centos7.9 创建日志存放目录 mkdir -p /opt/supervisor/log安装相关工具 yum install -y perl net-tools numactl gcc python-devel配置yum源 sudo vim /etc/yum.repos.d/mysql-community.repo [mysql-connectors-community] nameMySQL Connectors Com…...
Golang:精通sync/atomic 包的Atomic 操作
在本指南中,我们将探索sync/atomic包的细节,展示如何编写更安全、更高效的并发代码。无论你是经验丰富的Gopher还是刚刚起步,你都会发现有价值的见解来提升Go编程技能。让我们一起开启原子运算的力量吧! 理解Go中的原子操作 在快…...
微信小程序如何使用decimal计算金额
第三方库地址:GitHub - MikeMcl/decimal.js: An arbitrary-precision Decimal type for JavaScript 之前都是api接口走后端计算,偶尔发现这个库也不错,计算简单,目前发现比较准确 上代码 导入js import Decimal from ../../uti…...
最新Modular公司之MAX和Mojo作者 克里斯·拉特纳简介
Chris Lattner(克里斯拉特纳) 是一位著名的计算机科学家和软件工程师,以其在编程语言、编译器技术和软件开发工具领域的贡献而闻名。以下是关于他的详细介绍: 1. 主要成就 (1)LLVM 项目的创始人 Chris La…...
Redis数据库篇 -- Pipeline
一. 什么是Pipeline 在传统的请求-响应模式中,客户端与服务器之间的通信流程如下: 客户端发送一个命令到服务器。服务器接收命令并执行。服务器将执行结果返回给客户端。客户端接收结果后,发送下一个命令 在这种传统的模式下,…...
爬虫自动化(DrissionPage)
目录 ?一.介绍: 下载DrissionPage,还是我们熟悉的pip: 环境准备: ?二.基本代码: 它对于的导包和类使用: 窗口的设置: 和获取的页面的滑动: 3.进一步认识DrissionPage: 浏览器可以多开…...
常见string库中的函数(C语言超详细)
文章目录 strcspnstrcpystrncpystrcatstrncatstrcmpstrncmpstrchrstrrchrstrstrstrtokstrlenstrnlen strcspn 原型: size_t strcspn(const char *str1, const char *str2);功能: strcspn 会扫描 str1,并返回一个整数,表示 str1 中第一个匹配…...
单例模式几种实现
静态内部类holder实现(推荐) public class UniqueIdGenerator {public static final UniqueIdGenerator INSTANCE Holder.INSTANCE;// Private holder class for lazy initializationprivate static class Holder {static final UniqueIdGenerator INS…...
android中关于CheckBox自定义选中图片选中无效问题
在android xml 布局中,使用CheckBox控件设置选中背景图代码如下 <CheckBoxandroid:layout_width"wrap_content"android:layout_height"wrap_content"android:button"drawable/dfrd_common_selecotr_check"android:paddingStart&q…...
虚拟局域网之详解(Detailed Explanation of Virtual Local Area Network)
虚拟局域网之详解 VLAN (virtual localArea network)是一种虚拟局域网技术,它可以将一个物理局域网划分为多个逻辑上的虚拟局域网。 基于交换式以太网的虚拟局域网在交换式以太网中,利用VLAN技术,可以将由交换机连接成的物理网络划分成多个…...
双亲委派(JVM)
1.双亲委派 在 Java 中,双薪委派通常是指双亲委派模型,它是 Java 类加载器的一种工作模式,用于确保类加载的安全性和一致性。以下是其相关介绍: 定义与作用 定义:双亲委派模型要求除了顶层的启动类加载器外…...
第二十一章:考研的艰难抉择与放弃入学的转折
深秋时节,校园宛如被大自然精心雕琢的艺术殿堂。金黄的银杏叶在阳光的轻抚下,闪烁着细碎的光芒,微风拂过,叶片相互摩挲,发出沙沙的轻响,仿佛在低声诉说着岁月的故事。一片片银杏叶悠悠然飘落,宛…...
webpack配置之---output.chunkLoading
output.chunkLoading webpack.output.chunkLoading 配置项用于指定 Webpack 如何加载异步 chunk(即按需加载的代码块)。在现代 Webpack 版本中,异步代码分割成为了非常常见的功能,chunkLoading 配置项就用于控制 Webpack 加载这些…...
升级RAG应用程序与Redis向量库
Redis Vector Library (RedisVL) 简化AI应用开发 几个月前,Redis推出了Redis向量库(RedisVL),以简化人工智能(AI)应用的开发。自那时起,我们引入了强大的新功能,支持大规模的语言模…...
【starrocks学习】之将starrocks表同步到hive
目录 方法 1:通过HDFS导出数据 1. 将StarRocks表数据导出到HDFS 2. 在Hive中创建外部表 3. 验证数据 方法 2:使用Apache Spark同步 1. 添加StarRocks和Hive的依赖 2. 使用Spark读取StarRocks数据并写入Hive 3. 验证数据 方法 3:通过…...
HTML应用指南:利用GET请求获取全国盒马门店位置信息
随着新零售业态的发展,门店位置信息的获取变得至关重要。作为新零售领域的先锋,盒马鲜生不仅在商业模式创新上持续领先,还积极构建广泛的门店网络,以支持其不断增长的用户群体。本篇文章,我们将继续探究GET请求的实际应用,我们使用Python的requests库通过GET请求,从盒马…...
openEuler部署 sysstat工具
查看环境 [rootlocalhost lxm]# cat /etc/os-release NAME"openEuler" VERSION"23.09" ID"openEuler" VERSION_ID"23.09" PRETTY_NAME"openEuler 23.09" ANSI_COLOR"0;31"查看 yum 源 [rootlocalhost lxm]# he…...
使用 Three.js 实现炫酷的除夕烟花特效
1,前言 在除夕夜,璀璨的烟花点亮夜空,为节日增添了浓厚的喜庆氛围。在 Web 端,我们可以使用 Three.js 来模拟这种美轮美奂的烟花特效,让网页也能展现绚丽的节日气息。本文将介绍如何利用 Three.js 及其着色器技术&…...
LMM-3DP:集成 LMM 规划器和 3D 技能策略实现可泛化操作
25年1月来自UCSD的论文“Integrating LMM Planners and 3D Skill Policies for Generalizable Manipulation”。 大型多模态模型 (LMM) 的视觉推理能力和 3D 特征场语义丰富性的最新进展,拓展了机器人能力的范围。这些发展对于弥合 LMM 高级推理与利用 3D 特征场低…...
喜马拉雅音频本地化实战:绕过xm格式,直接获取mp3文件的两种方法对比
喜马拉雅音频本地化实战:两种高效获取MP3文件的技术方案深度评测 作为国内领先的音频分享平台,喜马拉雅拥有海量优质内容,但其特有的XM格式却给用户跨平台使用带来了困扰。许多技术爱好者尝试过各种转换工具,却发现市面上几乎没有…...
如何在Windows上快速安装安卓应用:APK Installer终极指南
如何在Windows上快速安装安卓应用:APK Installer终极指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想要在Windows电脑上运行安卓应用&…...
开源工具LMAO:通过浏览器自动化免费调用ChatGPT与Copilot API
1. 项目概述与核心价值如果你和我一样,是个喜欢折腾各种AI工具,但又对官方API的付费门槛、调用限制或者复杂的申请流程感到头疼的开发者,那么今天聊的这个项目,你一定会感兴趣。它叫LLM-API-Open,圈内朋友喜欢叫它LMAO…...
如何快速配置ComfyUI ControlNet预处理器:完整安装与使用指南
如何快速配置ComfyUI ControlNet预处理器:完整安装与使用指南 【免费下载链接】comfyui_controlnet_aux ComfyUIs ControlNet Auxiliary Preprocessors 项目地址: https://gitcode.com/gh_mirrors/co/comfyui_controlnet_aux ComfyUI ControlNet Aux预处理器…...
告别预装旧版Demo:详解mmWave SDK两种刷写模式(Demonstration vs. CCS Development)及适用场景
告别预装旧版Demo:详解mmWave SDK两种刷写模式(Demonstration vs. CCS Development)及适用场景 当你第一次拿到毫米波雷达评估模块(EVM)时,预装的Demo固件可能已经过时半年甚至更久。这时候你会面临一个关键…...
基于STM32的数控恒流源:从硬件闭环到软件PD调节的工程实践
1. 数控恒流源的核心需求与设计思路 第一次接触数控恒流源是在三年前的一个工业检测设备项目中,当时需要为传感器阵列提供精确的电流激励。传统模拟恒流方案遇到温度漂移问题,最终选择了STM32数控方案。这种方案最大的优势在于:硬件闭环保证响…...
APK Installer终极指南:如何在Windows上快速安装安卓应用?
APK Installer终极指南:如何在Windows上快速安装安卓应用? 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 还在为Windows上安装安卓应用而烦恼吗…...
怎样高效使用Mac微信插件:5大实用功能完全指南
怎样高效使用Mac微信插件:5大实用功能完全指南 【免费下载链接】WeChatExtension-ForMac A plugin for Mac WeChat 项目地址: https://gitcode.com/gh_mirrors/we/WeChatExtension-ForMac 想让你的Mac微信变得更加强大吗?WeChatExtension-ForMac正…...
FPGA生成SPWM的另一种思路:抛弃ROM,用DDS IP核与CORDIC算法实时生成正弦波
FPGA实时生成SPWM:基于DDS IP核与CORDIC算法的高效实现方案 在电力电子和电机控制领域,SPWM(正弦脉宽调制)技术因其优异的谐波特性和高效率而广受青睐。传统FPGA实现方案通常采用预存波形数据的ROM方法,虽然实现简单&a…...
德尔·考德威尔:从微波校准到计量标准,塑造现代精密测量的隐形基石
1. 一位计量学巨匠的遗产:从德尔考德威尔看精密测量的基石在电子工程与测试测量这个庞大而精密的领域里,我们常常关注的是最新的示波器带宽、最前沿的矢量网络分析技术,或是某个芯片的测试方案。然而,支撑起整个现代工业测量体系可…...
