本文讲解redis中海量数据去重利器布隆过滤器Bloom Filter,强烈建议先全文大概浏览一遍在进行操作,里面笔者遇到的坑大都记录了
1. windows安装make命令
如果想获取make编译好的redisbloom.so,在公众号算法小生中输入bloom即可
- 下载https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/安装
- 重命名C:\MinGW\bin\mingw-get.exe为make.exe
- C:\MinGW\bin添加到环境变量path中
如果遇到没有文件扩展“.js”的脚本引擎错误,则进入到注册表,定位计算机\HKEY_CLASSES_ROOT.js,将.js中默认值改为为JSFile即可,我的电脑是WebStorm2021惹的祸
# 安装版本为3.8,OK
C:\Users\Administrator>make -v
GNU Make 3.82.90
2. 安装redis bloom2.4.2
进入解压后文件夹,执行make
命令生成redisbloom.so文件
$ make
Makefile:20: deps/readies/mk/main: No such file or directory
Makefile:197: /defs: No such file or directory
Makefile:224: /rules: No such file or directory
make: *** No rule to make target '/rules'. Stop.
到github上找到deps/readies下载下来依赖的文件https://github.com/RedisLabsModules/readies/archive/refs/heads/master.zip解压到缺失目录中,对于t-digest-c也是同样,其实也可以根据git submodule update --init --recursive
切换下载对应版本也可以,不过github很慢
# 再次执行命令,查看对应位置代码,发现我们make版本太低,至少为4,好吧,老老实实安装linux版本make4.4版本吧,windows没找到
$ make
deps/readies/mk/main:6: *** GNU Make version is too old. Aborting.. Stop.
- 以下步骤为linux安装make4.4版本
make -v
wget http://ftp.gnu.org/gnu/make/make-4.4.tar.gz
tar -zxvf make-4.4.tar.gz
cd make-4.4
./configure
make install
which make
/usr/local/bin/make -v
cd /usr/bin
mv make make3.8
ln -s /usr/local/bin/make ./make
make -v
[root@iZuf6fjdhecwn46n83l0hqZ bin]# make -v
GNU Make 4.4
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
wget https://github.com/RedisBloom/RedisBloom/archive/refs/tags/v2.4.2.tar.gz
tar -zxvf v2.4.2.tar.gz
cd RedisBloom-2.4.2/
cd deps/readies/
wget https://github.com/RedisLabsModules/readies/archive/refs/heads/master.zip
unzip master.zip
mv readies-master/* .
rm -rf master.zip readies-master/
cd ../..
# centos7安装gcc
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
还有可能遇到cmake版本问题,自行升级吧
// 对于该错误,试过网上几个版本不可以,最后直接改源码,在make就通过了
/root/RedisBloom-2.4.2/deps/t-digest-c/src/tdigest.c:291:5: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int it = 0; it < n - 1; it++) {
^
- 成品redisbloom.so
[root@iZuf6fjdhecwn46n83l0hqZ RedisBloom-2.4.2]# make
Building /root/RedisBloom-2.4.2/bin/linux-x64-release/t-digest-c/src/libtdigest_static.a ...
Building /root/RedisBloom-2.4.2/bin/linux-x64-release/t-digest-c/libtdigest_static.a ...
Scanning dependencies of target tdigest_static
[ 50%] Building C object src/CMakeFiles/tdigest_static.dir/tdigest.c.o
[100%] Linking C static library libtdigest_static.a
[100%] Built target tdigest_static
Compiling deps/bloom/bloom.c...
Compiling deps/murmur2/MurmurHash2.c...
Compiling deps/rmutil/util.c...
Compiling src/rebloom.c...
Compiling src/sb.c...
Compiling src/cf.c...
Compiling src/rm_topk.c...
Compiling src/rm_tdigest.c...
Compiling src/topk.c...
Compiling src/rm_cms.c...
Compiling src/cms.c...
Linking /root/RedisBloom-2.4.2/bin/linux-x64-release/redisbloom.so...
3. 修改docker-compose.yml文件及redis.conf
version: '3'
services:
redis:
network_mode: bridge
container_name: redis
image: redis:7.0.5-alpine3.16
ports:
- 6379:6379
command: redis-server /usr/local/redis/conf/redis.conf
volumes:
- ./data:/data
- ./conf/redis.conf:/usr/local/redis/conf/redis.conf
- ./module/redisbloom.so:/usr/local/redis/module/redisbloom.so
sysctls:
- net.core.somaxconn=1024
privileged: true
environment:
- TZ=Asia/Shanghai
- LANG=en_US.UTF-8
# redis.conf中加载布隆过滤器
loadmodule /usr/local/redis/module/redisbloom.so
很抱歉,到此为止无法加载redisbloom.so,缺少依赖,懒的在镜像中下载了,还是老老实实在刚刚的linux上下载linux,配置redis.conf,加载布隆过滤器吧,真是个悲伤的故事
4. linux中安装redis7及加载模块
wget https://github.com/redis/redis/archive/7.0.5.tar.gz
tar -zxvf redis-7.0.5.tar.gz
cd redis-7.0.5
make
make install
# 修改redis.conf新增loadmodule /usr/local/redis/module/redisbloom.so后启动
./src/redis-server redis.conf
5. 重启redis并运行基本命令
# 添加
127.0.0.1:6379> bf.add url shenjian.online
(integer) 0
# 判断是否存在
127.0.0.1:6379> bf.exists url shenjian.online
(integer) 1
127.0.0.1:6379> bf.exists url fangjia.com
(integer) 0
5. 原理介绍
布隆过滤器(Bloom Filter)是一个高空间利用率的概率性数据结构,由二进制向量(即位数组)和一系列随机映射函数(即哈希函数)两部分组成。
布隆过滤器使用exists()来判断某个元素是否存在于自身结构中。当布隆过滤器判定某个值存在时,其实这个值只是有可能存在;当它说某个值不存在时,那这个值肯定不存在,这个误判概率大约在 1% 左右。
- 添加元素原理
布隆过滤器主要由位数组和一系列 hash 函数构成,其中位数组的初始状态都为 0。
当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。根据哈希值计算出一个整数索引值,将该索引值与位数组长度做取余运算,最终得到一个位数组位置,并将该位置的值变为 1。每个 hash 函数都会计算出一个不同的位置,然后把数组中与之对应的位置变为 1。通过上述过程就完成了元素添加(add)操作。
- 判定元素是否存在原理
当我们需要判断一个元素是否存时,其流程如下:首先对给定元素再次执行哈希计算,得到与添加元素时相同的位数组位置,判断所得位置是否都为 1,如果其中有一个为 0,那么说明元素不存在,若都为 1,则说明元素有可能存在。 - 为什么是可能“存在”
那些被置为 1 的位置也可能是由于其他元素的操作而改变的。比如,元素1 和 元素2,这两个元素同时将一个位置变为了 1(图1所示)。在这种情况下,我们就不能判定“元素 1”一定存在,这是布隆过滤器存在误判的根本原因。