引言
本篇主要介绍使用redis布隆过滤器插件实现布隆过滤器。Redis 4.0本版之后,增加了redis布隆过滤器的实现插件——rebloom,下面笔者带大家从安装到整合的项目使用一一道来。
1、安装布隆过滤器
在指定目录依次执行以下命令完成安装(本篇以目录/usr/local为例)
cd /usr/local
git clone git://github.com/RedisLabsModules/rebloom
cd rebloom
make
2、配置布隆过滤器插件安装目录
打开刚才安装的rebloom目录,找到redisbloom.so文件。找到后,复制完整路径。在redis.conf配置文件中,添加如下配置:
loadmodule /usr/local/rebloom/redisbloom.so
然后保存重启redis服务。
3、测试
打开命令方式进入redis的客户端,依次测试如下命令:
bf.add myRebloom bl1
bf.add myRebloom bl2
若返回1,说明执行成功。然后执行如下命令验证结果。
bf.exists myRebloom bl2
bf.exists myRebloom bl3
上面两条命令,分别验证了bl2和bl3这两个键的操作是否存在。很显然,bl3是不存在的,所有返回结果为了0,另一个是存在的,所以返回1。
4、Spring boot整合redis布隆过滤器
首先,要在Spring boot项目中正好redis,在此基础上,我们开始整合redis布隆过滤器。我们以上一篇的项目为例,再service包中添加实现类RedisBloomFilter,代码如下:
package com.example.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class RedisBloomFilter {
@Autowired
private RedisTemplate redisTemplate;
public Boolean bloomFilterAdd(String filterName, int value) {
DefaultRedisScript<Boolean> add = new DefaultRedisScript<>();
add.setScriptSource(new ResourceScriptSource(new ClassPathResource("bloomFilterAdd.lua")));
add.setResultType(Boolean.class);
List<Object> keyList = new ArrayList<>();
keyList.add(filterName);
keyList.add(value + "");
Boolean result = (Boolean) redisTemplate.execute(add, keyList);
return result;
}
public Boolean bloomFilterExists(String filterName, int value) {
DefaultRedisScript<Boolean> blExists = new DefaultRedisScript<>();
blExists.setScriptSource(new ResourceScriptSource(new ClassPathResource("bloomFilterExist.lua")));
blExists.setResultType(Boolean.class);
List<Object> list = new ArrayList<>();
list.add(filterName);
list.add(value + "");
Boolean result = (Boolean) redisTemplate.execute(blExists, list);
return result;
}
}
然后在resources目录中,添加bloomFilterAdd.lua和bloomFilterExist.lua,内容分别如下:
bloomFilterAdd.lua
local bloomName = KEYS[1]
local value = KEYS[2]
-- bloomFilter
local result_1 = redis.call('BF.ADD', bloomName, value)
return result_1
bloomFilterExist.lua
local bloomName = KEYS[1]
local value = KEYS[2]
-- bloomFilter
local result_1 = redis.call('BF.EXISTS', bloomName, value)
return result_1
接下来添加Controller类RedisController,代码如下:
package com.example.controller;
import com.example.service.impl.RedisBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/sys")
public class RedisController {
@Autowired
private RedisBloomFilter redisBloomFilter;
@GetMapping("redisidAdd/{id}")
public boolean redisidAdd(@PathVariable("id") int id) {
return redisBloomFilter.bloomFilterAdd("myBloom", id);
}
@GetMapping("redisidExists/{id}")
public boolean redisidExists(@PathVariable("id") int id) {
return redisBloomFilter.bloomFilterExists("myBloom", id);
}
}
好,代码添加完成后,启动项目,我们先访问添加接口,分别向布隆过滤器中添加两条数据。若返回true,说明添加成功。效果如下:
最后,调用查询接口,输入一个不存在的参数值,看看是不是会返回false,效果如下:
OK,大功告成。