首页 > 数据库 >2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?

2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?

时间:2023-06-11 21:01:52浏览次数:32  
标签:11 06 URL 布隆 哈希 过滤器 100 math

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浏览器也使用布隆过滤器来加速安全浏览服务。

2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?_数据结构

布隆过滤器的误判问题

Ø通过哈希计算得到的在数组上的位置并不一定代表元素真正存在于集合中

Ø误判问题的本质是哈希冲突,即不同的元素可能哈希到相同的数组位置

Ø如果一个元素的哈希值不在数组中,则一定不存在于集合中,但是如果哈希值在数组中,则存在误判的概率(误判)

2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?_布隆过滤器_02

优化方案

增大哈希数组的长度,使其能够容纳更多的元素。需要根据集合大小和误判率等因素,预估合适的数组长度;

增加哈希函数的数量,以减少哈希冲突的概率。多个哈希函数可以让元素哈希到多个位置上,从而降低误判率。

2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?_布隆过滤器_03

布隆过滤器重要的三个公式

1.假设数据量为n,预期的失误率为p(布隆过滤器大小和每个样本的大小无关)。

2.根据n和p,算出BloomFilter一共需要多少个bit位,向上取整,记为m。

3.根据m和n,算出BloomFilter需要多少个哈希函数,向上取整,记为k。

4.根据修正公式,算出真实的失误率p_true。

2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?_布隆过滤器_04

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是否存在?_数组_05

标签:11,06,URL,布隆,哈希,过滤器,100,math
From: https://blog.51cto.com/moonfdd/6458993

相关文章

  • English Learning Articles 2022-06-11 Your teen wants to get in shape this summer
    Yourteenwantstogetinshapethissummer?Whattosayandwhentoworry|CNN Ifyourchildrensaytheywanttostartexercisingorworkingoutmorethissummer,don’tcelebratejustyet.Iknowmostparentswouldbethrilledtoseetheirteenstakin......
  • leetcode 1171. 从链表中删去总和值为零的连续节点
    给你一个链表的头节点 head,请你编写代码,反复删去链表中由总和 值为0的连续节点组成的序列,直到不存在这样的序列为止。删除完毕后,请你返回最终结果链表的头节点。你可以返回任何满足题目要求的答案。(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)示例1:输入:he......
  • Leetcode 1171. 从链表中删去总和值为零的连续节点
    题目:给你一个链表的头节点 head,请你编写代码,反复删去链表中由总和 值为0的连续节点组成的序列,直到不存在这样的序列为止。删除完毕后,请你返回最终结果链表的头节点。你可以返回任何满足题目要求的答案。(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)难......
  • 6-11|Python中保证两位小数的方法
    如果你在Python编程过程中需要对输出结果限制小数点位数,那么这篇文章将为你提供多种可靠的方法。一、使用round()函数round()函数是Python内置函数,用于四舍五入,也可以限制小数点位数。num=3.1415926result=round(num,2)print(result)输出结果为3.14。这种方法非常简单,但是需......
  • Hugging News #0609: 最新代码生成模型 StarCoder+ 和 StarChat Beta 重磅发布!
    每一周,我们的同事都会向社区的成员们发布一些关于HuggingFace相关的更新,包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等,我们将其称之为「HuggingNews」,本期HuggingNews有哪些有趣的消息,快来看看吧!重磅更新StarCoder+和StarChatβ发布!......
  • 2023年6月11日,TreeSet,Comparable,HashMap
    1.Set1.TreeSetTreeSet1、存储Integer的元素,升序排列2、存储String的元素,字典排列TreeSet根据元素的不同类型使用不同的排序规则publicclasstest01{/***知识点:TreeSet*1、存储Integer的元素,升序排列*2、存储String的元素,字典排列*......
  • 【代码片段分享】比 url.QueryEscape 快 7.33 倍的 FastQueryEscape
    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!cnblogs博客zhihuGithub公众号:一本正经的瞎扯做profile发现url.QueryEscape占用的CPU时间较多,于是搜索到了一个资料:net/url:optimizeunescapeandescape.于是在这个代码的基础上改了FastQueryString的版......
  • LeetCode 双周赛 106(2023/06/10)两道思维题
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]加入知识星球提问。往期回顾:LeetCode单周赛第348场·数位DP模版学会了吗?双周赛106概览T1.判断一个数是否迷人(Easy)标签:计数T2.找到最长的半重复子字符串(Medium)标签:同向双指针T3.移动机......
  • 6/11 闲话
    学别人推个歌:逃避行——Imase歌词さよなら逃避行昨日の酔いも覚めない君と抜け出す街を行こう背負い込んだ重い過去も飲み込んだ思いすらも乗り越えた乗り越えた二人で錆びついたこの心も夢を見たあの気持ちと飛び込んだ飛び込んだ二人でさよなら......
  • 基于QT实现的影院票务系统[2023-06-11]
    基于QT实现的影院票务系统[2023-06-11]1系统权限管理系统分3种用户权限:A游客权限-注册会员,查看电影场次信息,购买电影票。B会员权限-登录系统,管理个人信息,查看电影场次信息,购买电影票。C票务管理权限-登录系统,管理电影场次信息,查看电影票售卖情况,管理会员。以上为基础需......