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是否存在?的更多相关文章

  1. 布隆过滤器 - 如何在100个亿URL中快速判断某URL是否存在?

    题目描述 一个网站有 100 亿 url 存在一个黑名单中,每条 url 平均 64 字节.这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中? 题目解析 这 ...

  2. 一道腾讯面试题:如何快速判断某 URL 是否在 20 亿的网址 URL 集合中?布隆过滤器

    何为布隆过滤器 还是以上面的例子为例: 判断逻辑: 多次哈希: Guava的BloomFilter 创建BloomFilter 最终还是调用: 使用: 算法特点 使用场景 假设遇到这样一个问题:一个网 ...

  3. springboot项目中如何在pom文件覆盖starter中默认指定的jar版本号

    分两种情况: 1.项目继承自spring-boot-starter-parent  通过定义properties的方式改变starter中的默认版本 <!-- Inherit defaults ...

  4. 庐山真面目之十三微服务架构中如何在Docker上使用Redis缓存

    一.介绍     1.开始说明 在微服务器架构中,有一个组件是不能少的,那就是缓存组件.其实来说,缓存组件,这个叫法不是完全正确,因为除了缓存功能,它还能完成其他很多功能.我就不隐瞒了,今天我们要探讨 ...

  5. 2022年5月11日,NBMiner发布了41.3版本,在内核中加入了100%LHR解锁器,从此NVIDIA的显卡再无锁卡一说

           2022年5月11日,NBMiner发布NBMiner_41.3版本,主要提升了稳定性.         2022年5月8日,NBMiner发布NBMiner_41.0版本,在最新的内核 ...

  6. redis事件监听及在订单系统中的使用

    https://blog.csdn.net/qq_37334135/article/details/77717248 通常在网上买好物品,或者说手机扫码后,点击付款,这时就会向后台发送请求,生成订单信 ...

  7. 如何在SSIS的脚本组件中访问变量

    原文:如何在SSIS的脚本组件中访问变量 这是一个小问题,我们在SSIS的设计中很多地方都会用到变量,我习惯性地将"变量"和"表达式"称为SSIS的灵魂,虽然不 ...

  8. 如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?

    我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供了扩展点使我们可以与第三方DI框架进行整合.对此比较了解的读 ...

  9. JAVAEE——宜立方商城06:Redis安装、数据类型和持久化方案、Redis集群分析与搭建、实现缓存和同步

    1. 学习计划 1.首页轮播图展示 2.Redis服务器搭建 3.向业务逻辑中添加缓存. 4.使用redis做缓存 5.缓存同步. 2. 首页轮播图动态展示 2.1. 功能分析 根据分类id查询内容列 ...

  10. 【MFC】如何在MFC创建的程序中更改主窗口的属性 与 父窗口 WS_CLIPCHILDREN 样式 对子窗口刷新的影响 与 窗体区域绘制问题WS_CLIPCHILDREN与WS_CLIPSIBLINGS

    如何在MFC创建的程序中更改主窗口的属性 摘自:http://blog.sina.com.cn/s/blog_4bebc4830100aq1m.html 在MFC创建的单文档界面中: (基于对话框的, ...

随机推荐

  1. bpmnjs的基本使用(vue)

    bpmn-js在vue中的基本使用 效果: 下载依赖包 npm i bpmn-js bpmn-js-properties-panel camunda-bpmn-moddle "bpmn-js ...

  2. Django笔记十五之in查询及date日期相关过滤操作

    这一篇介绍关于范围,日期的筛选 in range date year week weekday quarter hour 1.in in 对应于 MySQL 中的 in 操作,可以接受数组.元组等类型 ...

  3. 五月二十五日jdbc基础知识点

    Jdbc连接数据库1.建立与数据库的连接1.1导入jdbc包1.2加载JDBC驱动java.lang.Class.forName(JDBCDriverClass);Class.forName(driv ...

  4. Vue2异步更新及nextTick原理

    vue 官网中是这样描述 nextTick 的 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,可以获取更新后的 DOM. 在学习 nextTick 是如何实现之前,我们 ...

  5. kali 安装beef-xss (含输入正确密码却登录不了本机无法打开beef提示找不到服务器404常见解决办法)

    1:安装beef 2:修改配置文件 3:浏览器打开地址127.0.0.1:3000/ui/panel 常见问题解决本文最后 kali 打开终端 输入apt-get install beef-xss - ...

  6. 最新版本 Stable Diffusion 开源 AI 绘画工具之图生图进阶篇

    目录 图生图基本参数 图生图(img2img) 涂鸦绘制(Sketch) 局部绘制(Inpaint) 涂鸦蒙版(Inpaint sketch) 上传蒙版(Inpaint upload) 图生图基本参数 ...

  7. ubuntu容器的远程xface桌面环境搭建

    一.container: ubuntu20.04 二.commands: apt install xfce4 tigervnc-standalone-server  # xface使用gdm3启动器 ...

  8. Linux普通用户使用docker以及docker-compose

    # 添加limstorm普通用户到docker用户组 sudo gpasswd -a limstorm docker # 切换docker用户组,该命令类似login指令,当它是以相同的帐号,另一个群 ...

  9. 从原理聊JVM(一):染色标记和垃圾回收算法

    作者:京东科技 康志兴 1 JVM运行时内存划分 1.1 运行时数据区域 • 方法区 属于共享内存区域,存储已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据.运行时常量池,属于方法 ...

  10. DevOps、SRE、平台工程的区别

    DevOps.SRE和平台工程的概念在不同时期出现,并由不同的个人和组织开发. DevOps作为一个概念是由Patrick Debois和Andrew Shafer在2009年的敏捷会议上提出的.他们 ...