欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis?BloomFilter布隆過(guò)濾器原理與實(shí)現(xiàn)

 更新時(shí)間:2022年10月11日 09:25:19   作者:~龐貝  
你在開(kāi)發(fā)或者面試過(guò)程中,有沒(méi)有遇到過(guò)?海量數(shù)據(jù)需要查重,緩存穿透怎么避免等等這樣的問(wèn)題呢?下面這個(gè)東西超棒,好好了解下,面試過(guò)關(guān)斬將,凸顯你的不一樣

Bloom Filter 概念

布隆過(guò)濾器(英語(yǔ):Bloom Filter)是1970年由一個(gè)叫布隆的小伙子提出的。它實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制向量和一系列隨機(jī)映射函數(shù)。布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢(xún)時(shí)間都遠(yuǎn)遠(yuǎn)超過(guò)一般的算法,缺點(diǎn)是有一定的誤識(shí)別率和刪除困難。

Bloom Filter 原理

布隆過(guò)濾器的原理是,當(dāng)一個(gè)元素被加入集合時(shí),通過(guò)K個(gè)散列函數(shù)將這個(gè)元素映射成一個(gè)位數(shù)組中的K個(gè)點(diǎn),把它們置為1。檢索時(shí),我們只要看看這些點(diǎn)是不是都是1就(大約)知道集合中有沒(méi)有它了:如果這些點(diǎn)有任何一個(gè)0,則被檢元素一定不在;如果都是1,則被檢元素很可能在。這就是布隆過(guò)濾器的基本思想。

Bloom Filter跟單哈希函數(shù)Bit-Map不同之處在于:Bloom Filter使用了k個(gè)哈希函數(shù),每個(gè)字符串跟k個(gè)bit對(duì)應(yīng)。從而降低了沖突的概率

緩存穿透

每次查詢(xún)都會(huì)直接打到DB

簡(jiǎn)而言之,言而簡(jiǎn)之就是我們先把我們數(shù)據(jù)庫(kù)的數(shù)據(jù)都加載到我們的過(guò)濾器中,比如數(shù)據(jù)庫(kù)的id現(xiàn)在有:1、2、3

那就用id:1 為例子他在上圖中經(jīng)過(guò)三次hash之后,把三次原本值0的地方改為1

下次數(shù)據(jù)進(jìn)來(lái)查詢(xún)的時(shí)候如果id的值是1,那么我就把1拿去三次hash 發(fā)現(xiàn)三次hash的值,跟上面的三個(gè)位置完全一樣,那就能證明過(guò)濾器中有1的

反之如果不一樣就說(shuō)明不存在了

那應(yīng)用的場(chǎng)景在哪里呢?一般我們都會(huì)用來(lái)防止緩存擊穿

簡(jiǎn)單來(lái)說(shuō)就是你數(shù)據(jù)庫(kù)的id都是1開(kāi)始然后自增的,那我知道你接口是通過(guò)id查詢(xún)的,我就拿負(fù)數(shù)去查詢(xún),這個(gè)時(shí)候,會(huì)發(fā)現(xiàn)緩存里面沒(méi)這個(gè)數(shù)據(jù),我又去數(shù)據(jù)庫(kù)查也沒(méi)有,一個(gè)請(qǐng)求這樣,100個(gè),1000個(gè),10000個(gè)呢?你的DB基本上就扛不住了,如果在緩存里面加上這個(gè),是不是就不存在了,你判斷沒(méi)這個(gè)數(shù)據(jù)就不去查了,直接return一個(gè)數(shù)據(jù)為空不就好了嘛。

這玩意這么好使那有啥缺點(diǎn)么?有的,我們接著往下看

Bloom Filter的缺點(diǎn)

bloom filter之所以能做到在時(shí)間和空間上的效率比較高,是因?yàn)闋奚伺袛嗟臏?zhǔn)確率、刪除的便利性

存在誤判,可能要查到的元素并沒(méi)有在容器中,但是hash之后得到的k個(gè)位置上值都是1。如果bloom filter中存儲(chǔ)的是黑名單,那么可以通過(guò)建立一個(gè)白名單來(lái)存儲(chǔ)可能會(huì)誤判的元素。

刪除困難。一個(gè)放入容器的元素映射到bit數(shù)組的k個(gè)位置上是1,刪除的時(shí)候不能簡(jiǎn)單的直接置為0,可能會(huì)影響其他元素的判斷??梢圆捎?a href="http://www.dbjr.com.cn/article/264689.htm" target="_blank">Counting Bloom Filter

常見(jiàn)問(wèn)題

1、為何要使用多個(gè)哈希函數(shù)?

Hash本身就會(huì)面臨沖突,如果只使用一個(gè)哈希函數(shù),那么沖突的概率會(huì)比較高。例如長(zhǎng)度100的數(shù)組,如果只使用一個(gè)哈希函數(shù),添加一個(gè)元素后,添加第二個(gè)元素時(shí)沖突的概率為1%,添加第三個(gè)元素時(shí)沖突的概率為2%…但如果使用兩個(gè)哈希函數(shù),添加一個(gè)元素后,添加第二個(gè)元素時(shí)沖突的概率降為萬(wàn)分之4(四種可能的沖突情況,情況總數(shù)100x100)

go語(yǔ)言實(shí)現(xiàn)

package main
import (
	"fmt"
	"github.com/bits-and-blooms/bitset"
)
//設(shè)置哈希數(shù)組默認(rèn)大小為16
const DefaultSize = 16
//設(shè)置種子,保證不同哈希函數(shù)有不同的計(jì)算方式
var seeds = []uint{7, 11, 13, 31, 37, 61}
//布隆過(guò)濾器結(jié)構(gòu),包括二進(jìn)制數(shù)組和多個(gè)哈希函數(shù)
type BloomFilter struct {
	//使用第三方庫(kù)
	set *bitset.BitSet
	//指定長(zhǎng)度為6
	hashFuncs [6]func(seed uint, value string) uint
}
//構(gòu)造一個(gè)布隆過(guò)濾器,包括數(shù)組和哈希函數(shù)的初始化
func NewBloomFilter() *BloomFilter {
	bf := new(BloomFilter)
	bf.set = bitset.New(DefaultSize)

	for i := 0; i < len(bf.hashFuncs); i++ {
		bf.hashFuncs[i] = createHash()
	}
	return bf
}
//構(gòu)造6個(gè)哈希函數(shù),每個(gè)哈希函數(shù)有參數(shù)seed保證計(jì)算方式的不同
func createHash() func(seed uint, value string) uint {
	return func(seed uint, value string) uint {
		var result uint = 0
		for i := 0; i < len(value); i++ {
			result = result*seed + uint(value[i])
		}
		//length = 2^n 時(shí),X % length = X & (length - 1)
		return result & (DefaultSize - 1)
	}
}
//添加元素
func (b *BloomFilter) add(value string) {
	for i, f := range b.hashFuncs {
		//將哈希函數(shù)計(jì)算結(jié)果對(duì)應(yīng)的數(shù)組位置1
		b.set.Set(f(seeds[i], value))
	}
}
//判斷元素是否存在
func (b *BloomFilter) contains(value string) bool {
	//調(diào)用每個(gè)哈希函數(shù),并且判斷數(shù)組對(duì)應(yīng)位是否為1
	//如果不為1,直接返回false,表明一定不存在
	for i, f := range b.hashFuncs {
		//result = result && b.set.Test(f(seeds[i], value))
		if !b.set.Test(f(seeds[i], value)) {
			return false
		}
	}
	return true
}
func main() {
	filter := NewBloomFilter()
	filter.add("asd")
	fmt.Println(filter.contains("asd"))
	fmt.Println(filter.contains("2222"))
	fmt.Println(filter.contains("155343"))
}

輸出結(jié)果如下:

true
false
false

到此這篇關(guān)于Redis BloomFilter布隆過(guò)濾器原理與實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Redis BloomFilter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang實(shí)現(xiàn)HTTP代理突破IP訪問(wèn)限制的步驟詳解

    Golang實(shí)現(xiàn)HTTP代理突破IP訪問(wèn)限制的步驟詳解

    在當(dāng)今互聯(lián)網(wǎng)時(shí)代,網(wǎng)站和服務(wù)商為了維護(hù)安全性和保護(hù)用戶(hù)隱私,常常會(huì)對(duì)特定的IP地址進(jìn)行封鎖或限制,本文將介紹如何使用Golang實(shí)現(xiàn)HTTP代理來(lái)突破IP訪問(wèn)限制,需要的朋友可以參考下
    2023-10-10
  • 在Golang中實(shí)現(xiàn)RSA算法的加解密操作詳解

    在Golang中實(shí)現(xiàn)RSA算法的加解密操作詳解

    RSA 是一種非對(duì)稱(chēng)加密算法,廣泛使用于數(shù)據(jù)的安全傳輸,crypto/rsa 是 Golang 中實(shí)現(xiàn)了 RSA 算法的一個(gè)標(biāo)準(zhǔn)庫(kù),提供了生成公私鑰對(duì)、加解密數(shù)據(jù)、簽名和驗(yàn)簽等功能,本文給大家介紹了在Golang中實(shí)現(xiàn)RSA算法的加解密操作,需要的朋友可以參考下
    2023-12-12
  • goland設(shè)置控制臺(tái)折疊效果

    goland設(shè)置控制臺(tái)折疊效果

    這篇文章主要介紹了goland設(shè)置控制臺(tái)折疊效果,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • golang實(shí)現(xiàn)的文件上傳下載小工具

    golang實(shí)現(xiàn)的文件上傳下載小工具

    這篇文章主要介紹了golang實(shí)現(xiàn)的文件上傳下載小工具,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-12-12
  • Go?語(yǔ)言開(kāi)發(fā)環(huán)境搭建過(guò)程

    Go?語(yǔ)言開(kāi)發(fā)環(huán)境搭建過(guò)程

    這篇文章主要介紹了Go?語(yǔ)言開(kāi)發(fā)環(huán)境搭建過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • golang?使用sort.slice包實(shí)現(xiàn)對(duì)象list排序

    golang?使用sort.slice包實(shí)現(xiàn)對(duì)象list排序

    這篇文章主要介紹了golang?使用sort.slice包實(shí)現(xiàn)對(duì)象list排序,對(duì)比sort跟slice兩種排序的使用方式區(qū)別展開(kāi)內(nèi)容,需要的小伙伴可以參考一下
    2022-03-03
  • 一文理解Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn)

    一文理解Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn)

    本文主要介紹了Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Go中Context使用源碼解析

    Go中Context使用源碼解析

    這篇文章主要為大家介紹了Go中Context使用源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 一文帶你掌握Golang的反射基礎(chǔ)

    一文帶你掌握Golang的反射基礎(chǔ)

    go的反射是由其標(biāo)準(zhǔn)庫(kù)中的reflect包實(shí)現(xiàn),該reflect包實(shí)現(xiàn)了在運(yùn)行時(shí)進(jìn)行反射的能力,本篇主要介紹了reflect的常用的幾個(gè)方法,希望對(duì)大家有所幫助
    2023-02-02
  • Go語(yǔ)言命令行操作命令詳細(xì)介紹

    Go語(yǔ)言命令行操作命令詳細(xì)介紹

    這篇文章主要介紹了Go語(yǔ)言命令行操作命令詳細(xì)介紹,本文重點(diǎn)介紹了go build、go clean、go fmt、go get等命令,需要的朋友可以參考下
    2014-10-10

最新評(píng)論