2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?
2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?
答案2023-06-11:
传统数据结构的不足
当然有人会想,我直接将网页URL存入数据库进行查找不就好了,或者建立一个哈希表进行查找不就OK了。
当数据量小的时候,这么思考是对的,
确实,将值映射到 HashMap 的 Key,可以在 O(1) 的时间复杂度内返回结果,具有高效的优点。但是 HashMap 的实现也存在一些不足,例如存储容量占比较高。考虑到负载因子的存在,通常需要预留一定的空间,导致实际空间不能被完全利用。例如,如果有一个1000万大小的 HashMap,以String类型为Key(长度不超过16个字符,且非常少重复),以Integer类型为Value,需要占据多少空间呢?实际上,它将占用1.2GB内存。相比之下,存储1000万个int类型的数据只需要大约40MB空间,占比仅为3%;而存储1000万个Integer类型的数据则需要约161MB空间,占比高达13.3%。因此,一旦数据量增大到数亿级别,HashMap 所占据的内存大小将变得非常可观。
如果整个网页黑名单系统包含100亿个网页URL,则简单的数据库查找操作将非常费时,并且如果每个URL空间为64B,则整个系统需要的内存空间将达到640GB,这对于一般的服务器来说是一个非常大的需求,难以实现。
布隆过滤器
布隆过滤器简介
1970 年布隆提出了一种布隆过滤器的算法,用来判断一个元素是否在一个集合中。
这种算法由一个二进制数组和一个 Hash 算法组成。
本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。
实际上,布隆过滤器被广泛应用于网页黑名单系统、垃圾邮件过滤系统、爬虫网址判重系统等领域。Google 著名的分布式数据库 Bigtable 就使用了布隆过滤器来查找不存在的行或列,以减少磁盘查找的IO次数。此外,Google Chrome浏览器也使用布隆过滤器来加速安全浏览服务。

布隆过滤器的误判问题
Ø通过哈希计算得到的在数组上的位置并不一定代表元素真正存在于集合中
Ø误判问题的本质是哈希冲突,即不同的元素可能哈希到相同的数组位置
Ø如果一个元素的哈希值不在数组中,则一定不存在于集合中,但是如果哈希值在数组中,则存在误判的概率(误判)

优化方案
增大哈希数组的长度,使其能够容纳更多的元素。需要根据集合大小和误判率等因素,预估合适的数组长度;
增加哈希函数的数量,以减少哈希冲突的概率。多个哈希函数可以让元素哈希到多个位置上,从而降低误判率。

布隆过滤器重要的三个公式
1.假设数据量为n,预期的失误率为p(布隆过滤器大小和每个样本的大小无关)。
2.根据n和p,算出BloomFilter一共需要多少个bit位,向上取整,记为m。
3.根据m和n,算出BloomFilter需要多少个哈希函数,向上取整,记为k。
4.根据修正公式,算出真实的失误率p_true。

golang代码如下:
package main
import (
"fmt"
"math"
)
func main() {
p := 0.0001 //预期失误率,万分之一
n := 100_0000_0000.0 //数据量100亿
m := -n * math.Log(p) / (math.Ln2 * math.Ln2)
m = math.Ceil(m)
k := math.Ln2 * m / n
k = math.Ceil(k)
ptrue := math.Pow(1-math.Pow(math.E, -n*k/m), k)
fmt.Println("比特位m:", int(m))
fmt.Println("哈希函数个数k:", k)
fmt.Printf("真实失误率ptrue:%f%%\n", ptrue*100)
fmt.Printf("占用空间:%fG\n", m/8/1024/1024/1024)
}

2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?的更多相关文章
- 布隆过滤器 - 如何在100个亿URL中快速判断某URL是否存在?
题目描述 一个网站有 100 亿 url 存在一个黑名单中,每条 url 平均 64 字节.这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中? 题目解析 这 ...
- 一道腾讯面试题:如何快速判断某 URL 是否在 20 亿的网址 URL 集合中?布隆过滤器
何为布隆过滤器 还是以上面的例子为例: 判断逻辑: 多次哈希: Guava的BloomFilter 创建BloomFilter 最终还是调用: 使用: 算法特点 使用场景 假设遇到这样一个问题:一个网 ...
- springboot项目中如何在pom文件覆盖starter中默认指定的jar版本号
分两种情况: 1.项目继承自spring-boot-starter-parent 通过定义properties的方式改变starter中的默认版本 <!-- Inherit defaults ...
- 庐山真面目之十三微服务架构中如何在Docker上使用Redis缓存
一.介绍 1.开始说明 在微服务器架构中,有一个组件是不能少的,那就是缓存组件.其实来说,缓存组件,这个叫法不是完全正确,因为除了缓存功能,它还能完成其他很多功能.我就不隐瞒了,今天我们要探讨 ...
- 2022年5月11日,NBMiner发布了41.3版本,在内核中加入了100%LHR解锁器,从此NVIDIA的显卡再无锁卡一说
2022年5月11日,NBMiner发布NBMiner_41.3版本,主要提升了稳定性. 2022年5月8日,NBMiner发布NBMiner_41.0版本,在最新的内核 ...
- redis事件监听及在订单系统中的使用
https://blog.csdn.net/qq_37334135/article/details/77717248 通常在网上买好物品,或者说手机扫码后,点击付款,这时就会向后台发送请求,生成订单信 ...
- 如何在SSIS的脚本组件中访问变量
原文:如何在SSIS的脚本组件中访问变量 这是一个小问题,我们在SSIS的设计中很多地方都会用到变量,我习惯性地将"变量"和"表达式"称为SSIS的灵魂,虽然不 ...
- 如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?
我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供了扩展点使我们可以与第三方DI框架进行整合.对此比较了解的读 ...
- JAVAEE——宜立方商城06:Redis安装、数据类型和持久化方案、Redis集群分析与搭建、实现缓存和同步
1. 学习计划 1.首页轮播图展示 2.Redis服务器搭建 3.向业务逻辑中添加缓存. 4.使用redis做缓存 5.缓存同步. 2. 首页轮播图动态展示 2.1. 功能分析 根据分类id查询内容列 ...
- 【MFC】如何在MFC创建的程序中更改主窗口的属性 与 父窗口 WS_CLIPCHILDREN 样式 对子窗口刷新的影响 与 窗体区域绘制问题WS_CLIPCHILDREN与WS_CLIPSIBLINGS
如何在MFC创建的程序中更改主窗口的属性 摘自:http://blog.sina.com.cn/s/blog_4bebc4830100aq1m.html 在MFC创建的单文档界面中: (基于对话框的, ...
随机推荐
- 选择KV数据库最重要的是什么
本文分享自华为云社区<选择KV数据库最重要的是什么?>,作者:GaussDB 数据库 . 经常有客户提到KV数据库,但却偏偏"不要Redis".比如有个做安全威胁分析平 ...
- vue之写发表评论思路
后端接口 var express = require('express'); const sql = require('../sql') const Comment = require('../sql ...
- [CTF]upload-lab靶场day1
Pass-01 前端js绕过 拿到题目看hint提示判定在前端,用burp代理,将1.php后缀名更改为.png格式即可通过前端检测,而后在burp中对修改包内容,将1.png改为1.php即可绕过前 ...
- Python 人工智能 5秒钟偷走你的声音
介绍 Python 深度学习AI - 声音克隆.声音模仿,是一个三阶段的深度学习框架,允许从几秒钟的音频中创建语音的数字表示,并用它来调节文本到语音模型,该模型经过培训,可以概括到新的声音. 环境准备 ...
- 有关idea的使用部分
出现相关异常,提示类似粗在idea找不到相关的包加载失败. 执行mvn命令 mvn -U idea:idea 含义更新重新加载idea工程的相关jar
- odoo 开发入门教程系列-添加修饰
添加修饰 我们的房地产模块现在从商业角度来看是有意义的.我们创建了特定的视图,添加了几个操作按钮和约束.然而,我们的用户界面仍然有点粗糙.我们希望为列表视图添加一些颜色,并使一些字段和按钮有条件地消失 ...
- C#版本LINQ增强开源库
LINQ对应的中文名称是:语言集成查询,是对一系列直接将查询功能集成到C#语言技术的统称,我们最常用的场景是,用于数据库的查询功能. 在.Net中,本身对Objects也支持LINQ的扩展,但是对于一 ...
- 帝国cms7.5和7.2 搜素模板支持 php和灵动标签以及不起作用
帝国CMS搜索模板不支持动态标签调用,从7.0到7.2再到刚发布的7.5,帝国官方团队始终没解决这个问题,这很不方便,但是帝国的强大可以让我们忽略这个问题,今天老威就把这个bug的解决方法说一下. 第 ...
- JS执行机制--同步与异步
单线程JavaScript语言具有单线程的特点,同一个时间只能做一件事情.这是因为JavaScript脚本语言是为了处理页面中用户的交互,以及操作DOM而诞生的.如果对某个DOM元素进行添加和删除,不 ...
- 天梯赛L1-027 出租
一.问题描述 下面是新浪微博上曾经很火的一张图: 一时间网上一片求救声,急问这个怎么破.其实这段代码很简单,index数组就是arr数组的下标,index[0]=2 对应 arr[2]=1,index ...