1. 布隆过滤器的概念

布隆过滤器(Bloom Filter) 是由 Howard Bloom在1970年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员,即判定 “可能已存在和绝对不存在” 两种情况。如果检测结果为是,该元素不一定在集合中;但如果检测结果为否,该元素一定不在集合中,因此Bloom filter具有100%的召回率。

2. 布隆过滤器应用场景

垃圾邮件过滤

防止缓存击穿

比特币交易查询

爬虫的URL过滤

IP黑名单

查询加速【比如基于KV结构的数据】

集合元素重复的判断

3. 布隆过滤器工作原理

布隆过滤器的核心是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k。

下图表示有三个hash函数,比如一个集合中有x,y,z三个元素,分别用三个hash函数映射到二进制序列的某些位上,假设我们判断w是否在集合中,同样用三个hash函数来映射,结果发现取得的结果不全为1,则表示w不在集合里面。

工作流程:

第一步:开辟空间:

开辟一个长度为m的位数组(或者称二进制向量),这个不同的语言有不同的实现方式,甚至你可以用文件来实现。

第二步:寻找hash函数

获取几个hash函数,前辈们已经发明了很多运行良好的hash函数,比如BKDRHash,JSHash,RSHash等等。这些hash函数我们直接获取就可以了。

第三步:写入数据

将所需要判断的内容经过这些hash函数计算,得到几个值,比如用3个hash函数,得到值分别是1000,2000,3000。之后设置m位数组的第1000,2000,3000位的值位二进制1。

第四步:判断

接下来就可以判断一个新的内容是不是在我们的集合中。判断的流程和写入的流程是一致的。

4. 布隆过滤器的优缺点

1、优点:

有很好的空间和时间效率

存储空间和插入/查询时间都是常数。

Hash函数相互之间没有关系,方便由硬件并行实现。

不需要存储元素本身,在某些对保密要求非常严格的场合有优势。

布隆过滤器可以表示全集,其它任何数据结构都不能。

2、缺点:

误判率会随元素的增加而增加

不能从布隆过滤器中删除元素

5. 布隆过滤器注意事项

布隆过滤器思路比较简单,但是对于布隆过滤器的随机映射函数设计,需要计算几次,向量长度设置为多少比较合适,这个才是需要认真讨论的。

如果向量长度太短,会导致误判率直线上升。

如果向量太长,会浪费大量内存。

如果计算次数过多,会占用计算资源,且很容易很快就把过滤器填满。

6. Go实现布隆过滤器

1. 开源包简单演示

package main

import (

"fmt"

"github.com/willf/bitset"

"math/rand"

)

func main() {

Foo()

bar()

}

func Foo() {

var b bitset.BitSet // 定义一个BitSet对象

b.Set(1).Set(2).Set(3) //添加3个元素

if b.Test(2) {

fmt.Println("2已经存在")

}

fmt.Println("总数:", b.Count())

b.Clear(2)

if !b.Test(2) {

fmt.Println("2不存在")

}

fmt.Println("总数:", b.Count())

}

func bar() {

fmt.Printf("Hello from BitSet!n")

var b bitset.BitSet

// play some Go Fish

for i := 0; i < 100; i++ {

card1 := uint(rand.Intn(52))

card2 := uint(rand.Intn(52))

b.Set(card1)

if b.Test(card2) {

fmt.Println("Go Fish!")

}

b.Clear(card1)

}

// Chaining

b.Set(10).Set(11)

for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) {

fmt.Println("The following bit is set:", i)

}

// 交集

if b.Intersection(bitset.New(100).Set(10)).Count() == 1 {

fmt.Println("Intersection works.")

} else {

fmt.Println("Intersection doesn't work???")

}

}

2. 封装的方法:

//----------------------------------------------------------------------------

// @ Copyright (C) free license,without warranty of any kind .

// @ Author: hollson

// @ Date: 2019-12-06

// @ Version: 1.0.0

//------------------------------------------------------------------------------

package bloomx

import "github.com/willf/bitset"

const DEFAULT_SIZE = 2<<24

var seeds = []uint{7, 11, 13, 31, 37, 61}

type BloomFilter struct {

Set *bitset.BitSet

Funcs [6]SimpleHash

}

func NewBloomFilter() *BloomFilter {

bf := new(BloomFilter)

for i:=0;i< len(bf.Funcs);i++{

bf.Funcs[i] = SimpleHash{DEFAULT_SIZE,seeds[i]}

}

bf.Set = bitset.New(DEFAULT_SIZE)

return bf

}

func (bf BloomFilter) Add(value string){

for _,f:=range(bf.Funcs){

bf.Set.Set(f.hash(value))

}

}

func (bf BloomFilter) Contains(value string) bool {

if value == "" {

return false

}

ret := true

for _,f:=range(bf.Funcs){

ret = ret && bf.Set.Test(f.hash(value))

}

return ret

}

type SimpleHash struct{

Cap uint

Seed uint

}

func (s SimpleHash) hash(value string) uint{

var result uint = 0

for i:=0;i< len(value);i++{

result = result*s.Seed+uint(value[i])

}

return (s.Cap-1)&result

}

func main() {

filter := bloomx.NewBloomFilter()

fmt.Println(filter.Funcs[1].Seed)

str1 := "hello,bloom filter!"

filter.Add(str1)

str2 := "A happy day"

filter.Add(str2)

str3 := "Greate wall"

filter.Add(str3)

fmt.Println(filter.Set.Count())

fmt.Println(filter.Contains(str1))

fmt.Println(filter.Contains(str2))

fmt.Println(filter.Contains(str3))

fmt.Println(filter.Contains("blockchain technology"))

}

参考:

推荐:https://www.cnblogs.com/z941030/p/9218356.html

https://www.jianshu.com/p/01309d298a0e

https://www.cnblogs.com/zengdan-develpoer/p/4425167.html

https://blog.csdn.net/liuzhijun301/article/details/83040178

https://github.com/willf/bloom

golang实现的布隆过滤器_Golang中的布隆过滤器-Go语言中文社区相关推荐

  1. golang实现的布隆过滤器_Golang中的布隆过滤器

    目录 1. 布隆过滤器的概念 布隆过滤器(Bloom Filter) 是由 Howard Bloom在1970年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一 ...

  2. linux命令界面下载kettle,kettle在linux环境中打开图形界面-Go语言中文社区

    kettle在linux环境中打开图形界面 kettle数据转换的时候需要图形界面 当运行./spoon.sh时,如果没有图形界面,会出现下面的结果 ./spoon.sh [root@localhos ...

  3. linux怎么看go写的程序进程,Linux中查看进程状态信息-Go语言中文社区

    Linux中查看进程状态信息 一.常用命令总结 ps -l   列出与本次登录有关的进程信息: ps -aux   查询内存中进程信息: ps -aux | grep ***   查询***进程的详细 ...

  4. rust的矿坑_转: Rust中的Pin详解 【Rust语言中文社区】

    Rust中的Pin详解 原创 automanyang Rust语言中文社区 昨天 https://mp.weixin.qq.com/s/PjctbPbyR5OeaqTHZdB5uQ 相关概念 Pin ...

  5. go 调用winapi_如何在go中调用windows api-Go语言中文社区

    1.cgo环境搭建 初入go坑,记录一次工作中需要封装windows api 的过程.既然是go调用C++那么首先要配置cgo的环境了.要使用CGO特性,需要安装C/C++构建工具链,在macOS和L ...

  6. golang mysql 事务_golang的嵌套事务管理-Go语言中文社区

    golang的事务管理是一件很麻烦的事,,能不能像Java那样,通过Spring管理事务,最近琢磨了一下,写了一个demo,用来管理golang的事务,使其支持golang事务的嵌套调用. 其思想很简 ...

  7. go语言能编android程序吗,用 Golang 开发 Android 应用(二)—— 简单 UI-Go语言中文社区...

    计划按以下的内容更新 简单 UI 关于开发一个应用,要有自己的应用名(显示用),和包名(真正唯一的应用名),简单说一台 Android 手机中所有应用的包名是唯一的,如果新安装的应用包名和已安装的应用 ...

  8. 服务器系统goha,推荐一个轻量级且高性能的 Golang 网络库:gnet-Go语言中文社区...

    image Github 主页 博客原文 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Event-Loop 事件驱动的高性能和轻量级网络 ...

  9. gorm软删除_GORM中文文档-Go语言中文社区

    入门指南 GORM是类似Django ORM,对开发人员友好的 Golang ORM 库. 概览 全特性 ORM (几乎包含所有特性) 模型关联 (一对一, 一对多,一对多(反向), 多对多, 多态关 ...

最新文章

  1. webform(七)分页
  2. MySQL安装过程启动mysqld_safe中提示的pid ended错误导致无法启动问题处理
  3. linux没有日志如何排错,在 Linux 中使用日志来排错
  4. redis 4.0.8 源码包安装集群
  5. Rundll32使用技巧
  6. 前端必备知识点—SVG
  7. LoadRunner如何监控Linux下的系统资源
  8. 从RGB到Lab色彩空间的转换
  9. Oracle如何一次插入多条数据
  10. FBA4droid 模拟器
  11. 计算机画图工具介绍PPT,怎么用思维导图制作PPT课件,迅捷画图软件讲解
  12. 道高一尺,魔高一丈--加密与解密的此消彼长
  13. 深度学习分类pytorch_pytorch使用转移学习的狗品种分类器
  14. JavaSE语法(3)——【逻辑控制:各种分支循环语句】
  15. MATLAB设计控制系统仿真实验,基于MATLAB的自动控制原理实验仿真系统的设计
  16. Android : Broadcast
  17. MyEclipse 10 注册码 破解 到期限制
  18. NAT 网络地址转换
  19. modern android5.1,modern warships
  20. Python——多线程与多进程

热门文章

  1. Pytorch深度学习实战教程(一):语义分割基础与环境搭建
  2. Java枚举类——valueOf()的用法
  3. 2023年美国大学生数学建模MCM问题Y:了解二手帆船的价格-解题思路及代码分享
  4. 小论文查重率一般小于多少?
  5. 5G网络切片的七种武器(三)
  6. 202205 移动硬盘拷贝内容至 银河麒麟
  7. pod概述:概念、原理解读
  8. 如何使用W5100S-EVB-Pico连接Azure物联网中心
  9. Excel自动为有值的单元格添加边框
  10. 使用swagger2markup导出API接口文档