布隆过滤器 redis_redis中的布隆过滤器

什么是布隆过滤器以及它的作用

7d74d65c231bd3d1c1a6768a59fe240e.png

布隆过滤器的工作原理:

  1. 将一个key通过不同的hash算法散列到不同的bit位上
  2. 当某个hash算法得到的位之前没有置位过,那么这个key肯定之前没有出现过
  3. 注意,如果某个key通过所有的hash算法得到的位之前都置位过,并不能确定这个这个key之前出现过,因为存在hash碰撞,大量key通过hash算法处理后总会有散列在相同位上的

所以布隆过滤器,顾名思义,是个过滤器,它能过滤出肯定不存在,没有出现过的key,并且随着hash算法的增多,以及bit列表长度的增加,hash碰撞的概率降低,它的误判率也会随之降低(但是永远不可能为0)

我们假设现在有6个hash算法,那么我们会有6个bit列表,假设每个bit列表占用10M内存,那么总共占用内存为60M,但是,10M代表了8000多万个bit位,6个bit列表的相互杂交,上亿的key也能轻松应对(切记,勿要忘记处理hash碰撞)

Redis中如何使用布隆过滤器

如今的互联网使用人群如此的庞大,为了支撑某个业务,我们使用的通常都是分布式的系统,因此布隆过滤器的设计也要考虑到分布式场景。

redis是我们开发中最常用的中间件,有些公司甚至直接把它当DB使用,上千G的redis集群在大公司中也经常出现。将布隆过滤器存储在redis中也是最常见的做法。

废话不多说我们直接来看代码,如何在redis中设计一个布隆过滤器

方法1:

其实很简单,redis已经给我们提供了所有的功能,lua脚本执行以及setbit指令。我们只需要设计好key就可以了。

//return 0 -------- key was not in bloom
//return 1 -------- key maybe in bloom.if need 100% correct result,then need other check,and that is not bloom's business
var bloomlua = `local r1=redis.call("SETBIT","{"..KEYS[1].."}1",ARGV[1],1)
local r2=redis.call("SETBIT","{"..KEYS[1].."}2",ARGV[2],1)
local r3=redis.call("SETBIT","{"..KEYS[1].."}3",ARGV[3],1)
local r4=redis.call("SETBIT","{"..KEYS[1].."}4",ARGV[4],1)
local r5=redis.call("SETBIT","{"..KEYS[1].."}5",ARGV[5],1)
local r6=redis.call("SETBIT","{"..KEYS[1].."}6",ARGV[6],1)
if(r1==0 or r2==0 or r3==0 or r4==0 or r5==0 or r6==0)
then
	return 0
end
return 1`

var testkey string = "testbloom"
var bitnum int64 = 8 * 1024 * 64 //64k

func main() {
	bloomkey := getbloomkey(testkey)
	index1 := hash1(testkey) % bitnum
	index2 := hash2(testkey) % bitnum
	index3 := hash3(testkey) % bitnum
	index4 := hash4(testkey) % bitnum
	index5 := hash5(testkey) % bitnum
	index6 := hash6(testkey) % bitnum

	//return 0 -------- key was not in bloom
	//return 1 -------- key maybe in bloom.if need 100% correct result,then need other check,and that is not bloom's business
	redis.EXEC("EVAL", bloomlua, 1, bloomkey, index1, index2, index3, index4, index5, index6)
}
func getbloomkey(key string) string {
	index := hash1(key)
	index = index % 100
	//one bloom use 100 bloomkeys
	//this can disperse keys to all redis servers when in cluster mode
	return fmt.Sprintf("bloom_%d", index)
}
func hash1(key string) int64 {
	var caculate int64
	//caculate
	return caculate
}
func hash2(key string) int64 {
	var caculate int64
	//caculate
	return caculate
}
func hash3(key string) int64 {
	var caculate int64
	//caculate
	return caculate
}
func hash4(key string) int64 {
	var caculate int64
	//caculate
	return caculate
}
func hash5(key string) int64 {
	var caculate int64
	//caculate
	return caculate
}
func hash6(key string) int64 {
	var caculate int64
	//caculate
	return caculate
}

方法2:

redis在4.0版本支持了插件模式,因此有官方支持的布隆过滤器插件,只要你启动redis服务器时启用了该插件就可以使用redis插件内置的布隆过滤器指令,就像使用set,exists这样的正常redis指令一样

插件地址:

RedisBloom/RedisBloom​github.com
e3599b47e55b73937744f20bcf62d3cd.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值