Bloomfilter
布隆过滤器是一种快速检索当前词汇是不是在字典中的一种数据结构。其实就是一个很长的的二进制向量,而且这个检索具有很大的局限性,但是对于减缓缓存击穿有很大的作用
图片来源:https://juejin.im/post/5cfd060ee51d4556f76e8067。
用处
一般是Redis的缓冲层,数据查询到来时,首先通过该过滤器过滤,用来最大程度的减轻Redis缓存穿透。
使用Go语言实现
先随便找个位置,建一个文件夹。进入该文件夹
(1)把源码包下载下来:
git clone https://github.com/RedisBloom/RedisBloom.git
下载完成以后,会有一个RedisBloom的文件夹,进入该文件夹:
make
编译源码之后,就会生成一个.so文件,这个东西,可以理解为win下的动态链接库,linux是没有dll文件的,但是有.so
(2)修改配置文件:进入redis所在的文件夹,把redis.conf拷贝一份:
cp redis.conf ./redis2.conf
(3)把刚才编译好的东西mv到redis的文件夹内(也可以不mv)
(4)打开刚copy好的redis2.conf,在第44行修改:
把loadmodule这个参数指定为刚才生成的.so文件,所以这里可以省略掉第三步,只要路径填对就行
(5)启动Redis(这里需要指定配置文件 redis-server redis2.conf),如果不写配置文件,默认读取的是redis.conf
代码示例
一个简单的逻辑,把数据库中所有的数据拿出来初始化过滤器。
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
type people struct {
ID string `gorm:"type:varchar(20);primary_key"`
Name string `gorm:"type:varchar(20);"`
}
func main(){
db, err:=redis.Dial("tcp","127.0.0.1:6379")
if err!=nil{
fmt.Println(err)
}
dbMySQL, err:= gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8")
defer dbMySQL.Close()
if err!=nil{
fmt.Print(err)
panic("open MySQL error")
}
users:=getALL(dbMySQL)
fmt.Println("当前的人数:",len(users))
for i:=0;i<len(users);i++{
e1,e2:=db.Do("bf.add","filter",users[i].ID)
fmt.Println(e1,e2)
}
fmt.Println("bloomMap初始化成功")
for i:=0;i<100;i++{
var id string
fmt.Scan(&id)
res, _ :=db.Do("bf.exists","filter",id)
fmt.Println(res)
}
}
func getALL(db *gorm.DB)([]people){
users:=[]people{}
err:=db.Model(&people{}).Find(&users).Error
if err!=nil{
fmt.Print("获取失败")
return nil
}
return users
}