亿级数据过滤和布隆过滤器

如何高效实现存在判断

在刷抖音时你有刷到过重复的推荐内容 吗?这么多的推荐内容要推荐给这么多的用户,它是怎么保证每个用户在看推荐内容时,保证不会出现之前已经看过的推荐视频呢?也就是说,抖音是如何实现 推送去重 的呢?
你会想到服务器 记录 了用户看过的 所有历史记录,当推荐系统推荐短视频时会从每个用户的历史记录里进行 筛选,过滤掉那些已经存在的记录。问题是当 用户量很大,每个用户看过的短视频又很多的情况下,这种方式,推荐系统的去重工作 在性能上跟的上么?实际上,如果历史记录存储在关系数据库里,去重就需要频繁地对数据库进行 exists 查询,当系统并发量很高时,数据库是很难抗住压力的。
你可能又想到了 缓存,但是这么多用户这么多的历史记录,如果全部缓存起来,那得需要 浪费多大的空间。并且这个存储空间会随着时间呈线性增长,就算你用缓存撑得住一个月,但是又能继续撑多久呢?不缓存性能又跟不上,咋办呢?

布隆过滤器是什么

布隆过滤器(Bloom Filter) 是 1970 年由布隆提出的。可以把它 简单理解 为一个不怎么精确的 set 结构,当你使用它的 contains 方法判断某个对象是否存在时,它可能会误判。但是布隆过滤器也不是特别不精确,只要参数设置的合理,它的精确度可以控制的相对足够精确,只会有小小的误判概率。当布隆过滤器说某个值存在时,这个值 可能不存在;当它说不存在时,那么 一定不存在。

布隆过滤器的使用场景

基于上述的功能,我们大致可以把布隆过滤器用于以下的场景之中:

  • 大数据判断是否存在:这就可以实现出上述的去重功能,如果你的服务器内存足够大的话,那么使用 HashMap 可能是一个不错的解决方案,理论上时间复杂度可以达到 O(1 的级别,但是当数据量起来之后,还是只能考虑布隆过滤器。
  • 解决缓存穿透:我们经常会把一些热点数据放在 Redis 中当作缓存,例如产品详情。 通常一个请求过来之后我们会先查询缓存,而不用直接读取数据库,这是提升性能最简单也是最普遍的做法,但是 如果一直请求一个不存在的缓存,那么此时一定不存在缓存,那就会有 大量请求直接打到数据库 上,造成 缓存穿透,布隆过滤器也可以用来解决此类问题。
  • 爬虫/ 邮箱等系统的过滤:平时不知道你有没有注意到有一些正常的邮件也会被放进垃圾邮件目录中,这就是使用布隆过滤器 误判 导致的。

布隆过滤器原理解析

布隆过滤器的工作原理主要基于位数组和哈希函数。布隆过滤器是一种高效的多哈希函数概率型数据结构,它利用位数组和哈希函数来测试一个元素是否属于集合。以下是从不同方面去了解布隆过滤器的原理:

  • 数据结构:布隆过滤器使用了一个大的位数组和多个哈希函数。在初始化时,所有的位都被设置为0。当添加一个元素到布隆过滤器时,该元素会被每个哈希函数处理,得到相应的哈希值,然后在位数组中的对应位置上置为1。这样,当查询一个元素时,如果所有哈希函数计算出的位置上的位都是1,那么认为该元素可能存在于集合中;如果有任意一个位置上的位是0,那么该元素肯定不在集合中。
  • 空间计算:布隆过滤器的空间需求取决于预计要存储的元素数量和可接受的误判率。通过算法可以计算出所需的位数组大小和哈希函数的数量。较大的位数组和较多的哈希函数可以降低误判率,但会增加计算量和所需内存。
  • 增加元素:向布隆过滤器中添加新元素时,需要用所有哈希函数对该元素进行处理,得到的结果用来定位位数组中哪些位置需要被标记为1。这个过程可能会引起位数组中某些位从0变为1的变化,这是正常的。
  • 查询元素:查询操作涉及使用相同的哈希函数集对目标元素进行哈希处理,检查对应的位数组位置是否全为1。如果全部位都是1,则元素可能已存在;如果任意一个位置上的位是0,那么该元素肯定不存在。
  • 删除元素难度:布隆过滤器不支持删除操作,因为一个位可能会被多个元素所共享。如果尝试删除某个位,可能会错误地影响其他元素的检测结果。

布隆过滤器的基本用法

在这里插入图片描述

布隆过滤器有两个基本指令, bf.add 添加元素, bf.exists 查询元素是否存在,它的用法和 set 集合的 sadd 和 sismember 差不多。注意 bf.add 只能一次添加一个元素,如果想要一次添加多个,就需要用到 bf.madd 指令。同样如果需要一次查询多个元素是否存在,就需要用到 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.add codehole user3
(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) 1
127.0.0.1:6379> bf.exists codehole user4
(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

上面使用的布隆过过滤器只是默认参数的布隆过滤器,它在我们第一次 add 的时候自动创建。Redis也提供了可以自定义参数的布隆过滤器,只需要在 add 之前使用 bf.reserve 指令显式创建就好了。如果对应的 key 已经存在, bf.reserve 会报错。

布隆过滤器代码实现

以下实现包括了三个哈希函数(hash1、hash2、hash3),以及添加元素和判断元素是否存在的方法(add、contains)。

public class BloomFilter {

    private byte[] data;
    public BloomFilter(int initSize) {
        this.data = new byte[initSize * 2]; // 默认创建大小 * 2 的空间
    }
    public void add(int key) {
        int location1 = Math.abs(hash1(key) % data.length);
        int location2 = Math.abs(hash2(key) % data.length);
        int location3 = Math.abs(hash3(key) % data.length);
        data[location1] = data[location2] = data[location3] = 1;
    }
    public boolean contains(int key) {
        int location1 = Math.abs(hash1(key) % data.length);
        int location2 = Math.abs(hash2(key) % data.length);
        int location3 = Math.abs(hash3(key) % data.length);
        return data[location1] * data[location2] * data[location3] == 1;
    }
    private int hash1(Integer key) {
        return key.hashCode();
    }

    private int hash2(Integer key) {
        int hashCode = key.hashCode();
        return hashCode ^ (hashCode >>> 3);
    }
    private int hash3(Integer key) {
        int hashCode = key.hashCode();
        return hashCode ^ (hashCode >>> 16);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/677801.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java 工作排序(Job Sequencing Problem)

给定一个作业数组,其中每个作业都有一个截止期限,如果作业在截止期限之前完成,则可获得相关利润。此外,每个作业都占用一个单位时间,因此任何作业的最小可能截止期限都是 1。如果一次只能安排一项作业,则最…

开源规则引擎LiteFlow项目应用实践

本文介绍基于开源规则引擎LiteFlow,如何开发规则设计器,在低代码平台中集成规则引擎,并在项目中实现应用的效果。由于低代码平台使用规则引擎实现了逻辑编排的需求,所以本文中的叫法为“逻辑设计”、“逻辑编排”、“逻辑流引擎”…

RabbitMQ学习笔记(二)SpringAMQP的使用、消息转换器

文章目录 前言3 SpringAMQP3.1 介绍3.2 简单队列模型3.3 工作队列模型3.4 发布/订阅模型3.4.1 Fanout广播模型3.4.2 Direct定向模型3.4.3 Topic通配符模型 3.5 消息转换器 前言 RabbitMQ学习笔记(一)RabbitMQ部署、5种队列模型 3 SpringAMQP 3.1 介绍 AMQP(Adva…

白酒:产地与白酒品牌形象的建设与推广

云仓酒庄豪迈白酒作为中国白酒市场中的知名品牌,其产地与品牌形象的建设与推广对于提升品牌竞争力和市场份额具有重要意义。产地作为白酒品质和特色的重要标志,对于品牌形象的塑造和推广具有关键作用。 首先,云仓酒庄豪迈白酒的产地是其品质和…

AI降痕工具使用指南:如何有效降低AIGC疑似度

随着人工智能技术的突飞猛进,AI生成内容(AIGC)已被广泛用于学术论文撰写中,提高效率同时也带来了原创性的挑战。面对日益严格的学术审查,一个突出的问题是:使用AI代写的论文能否通过内容检测?因…

第二证券股票杠杆:4分钟直线涨停!这一赛道,AH股集体爆发!

今日早盘,A股继续小幅震动收拾,首要股指涨跌互现,两市个股跌多涨少,成交有萎缩的趋势。 盘面上,医药、中字头、旅游、房地产等板块相对活跃,混合实践、玻璃基板、AI手机PC、光刻机等板块跌幅居前。 “中字…

活动投票小程序源码系统 礼物道具活动多多 前后端分离 带完整的安装代码包以及搭建教程

系统概述 在当今数字化快速发展的时代,小程序已成为连接用户与商家、内容与服务的重要桥梁。特别是活动投票类小程序,因其便捷性、互动性和参与性,受到了广大用户的热烈追捧。为了满足市场对高质量、易操作的活动投票小程序的需求&#xff0…

别慌!不知道如何处理#开头的字符串时,需要先了解一下什么是NCR

最近进行接口测试时抓包发现请求响应中有类似下面这些字符 起初试图对这些编码尝试各种decoder操作来一探其真身,遗憾的是均已失败告终(后来发现,这些编码可以在浏览器中正常显示)。最后得知这种奇怪的编码格式并不是编码,而是一种…

ClickHouse 实现用户画像(标签)系统实践

文章目录 前言用户画像概述用户画像系统介绍用户画像系统的需求描述用户画像系统的需求分析用户画像系统的架构 关键技术实现(Clickhouse SQL)分析阶段运营阶段 基于ClickHouse的用户画像系统的优点 前言 本文介绍一个ClickHouse应用案例—用户画像系统…

AI工具:解锁智能时代办公自动化的新篇章

工欲善其事,必先利其器。 随着AI技术与各个行业或细分场景的深度融合,日常工作可使用的AI工具呈现出井喷式发展的趋势,AI工具的类别也从最初的AI文本生成、AI绘画工具,逐渐扩展到AI思维导图工具、AI流程图工具、AI生成PPT工具、AI…

AIGC| 有手就行的AI绘画教程!Midjourney+Stable Diffusion 结合!全程干货,速来学习!

大家好,我是画画的小强 AI绘画工具的出现, 让设计岗的同事更会画画了, 还让策划/制片/三维/后期/运营……也能“画”一画了。 今天小强就教一教大伙,萌新小白都能迅速上手的AI绘画教程, 从零开始,产出…

静态网页实现-人脸识别-案例(web)

🤳人脸识别(web) 基于开源大模型,将人脸识别功能整合到网页中,提供用户友好的界面和强大的功能。 核心功能 人脸轮廓识别: 通过深度学习算法,精确识别人脸的轮廓,包括眼睛、鼻子、嘴巴等关键部…

Java18+​App端采用uniapp+开发工具 idea hbuilder智能上门家政系统源码,一站式家政服务平台开发家政服务

Java18​App端采用uniapp开发工具 idea hbuilder智能上门家政系统源码,一站式家政服务平台开发 家政服务 家政服务是一个专为家政服务人员设计的平台,该平台旨在提供便捷、高效的工作机会,同时确保服务质量和客户体验。 以下是关于家政服务师…

【耗时十个小时】程序员最趁手的SVM算法,学完你会哭着感谢努力的自己!

❤ 纯 干 货 ❤ 在这之前咱们已经接触了 各个算法的优缺点的总结,以及8个回归类算法、7个正则化算法的总结、5 个集成算法模型的全部总结! 感兴趣的可以翻到之前看看~ 咱们今天就大概一起学习一下关于SVM的方方面面。 线性支持向量机 非线性支持向量…

干货 | SDR RFSoC技术框图大放送(附资源)

软件无线电(SDR) 本文参考《Software Defined Radio with Zynq UltraScale RFSoc》,全文共744页。需要的可以给公众号 迪普微科技 发送“SDR”。

动态规划——打家劫舍问题

198. 打家劫舍 问题描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一…

MathorCup挑战赛获奖名单公示,第九届研讨会及颁奖典礼即将举行

近日,备受瞩目的2024年第十四届MathorCup高校数学建模挑战赛圆满落幕,竞赛组委会于近日公示了获奖名单初稿。本届竞赛自2024年4月12日至16日举行,吸引了来自全国740所高校的9119支队伍踊跃参与,其中包括本科生、研究生、专科生及教…

Java流程控制习题--打印三角形及debug运用

1.打印三角形 使用for循环的嵌套进行运算,思考代码实现的思维方式 2.debug可显示代码每一步的运行步骤,使我们更好的了解代码的运行, debug使用方法:在代码的左侧排序处单机,在点击右上角的蜘蛛图标即可

springboot+elementui健康饮食系统

此系统是springboot健康饮食管理平台 得简化版,适合期末大作业 系统包括 管理员端和用户端 1.用户端注册即可登录到用户端,用户端包括首页轮播图,以及个人中心,个人信息修改,头像修改,后台根据用户信息&am…

liunx配置网络的命令

liunx配置网络的命令 文章目录 liunx配置网络的命令ifconfig命令查看路由表信息netstat命令ss命令lsof命令ping 命令nslookup命令 ifconfig命令 ifconfig:显示正在工作的网卡&#xff0c;启动的设备 ifconfig -a 展示所有设备 ens33: flags4163<UP,BROADCAST,RUNNING,MUL…