SpringBoot+Redis的Bloom过滤器
1.保姆级Linux安装Redis
①把redis.tar.gz下载到linux中,并用命令tar -zxvf安装
②安装完成进入目录输入make进行编译,编译完成后输入make install 进行安装
③创建两个文件夹mkdir bin mkdir etc
将redis目录下的redis.conf文件移动到etc文件中:mv redis.conf etc
将redis目录下src目录中的mkreleasehdr.sh、redis-benchmark、redis-check-aof、redis-cli、redis-server文件移动到 bin文件夹中:mv mkreleasehdr.sh redis-benchmark redis-check-aof redis-cli redis-server /root/home/softwear/redis-6.2.1/bin
④进入etc中打开redis.conf文件,修改配置(例如输入/daemonize查找按n键查找下一个):
- 把文件中的daemonize属性改为yes(表明需要在后台运行)
- 把?redis.conf配置文件中的 bind 127.0.0.1 这一行给注释掉,这里的bind指的是只有指定的网段才能远程访问这个redis,注释掉后,就没有这个限制了。
- 把?redis.conf配置文件中的 protected-mode 设置成no(默认是设置成yes的, 防止了远程访问
- 编辑 redis.conf配置文件,修改Redis默认密码 (默认密码为空)(1)在配置文件中找到这一行 # requirepass foobared(2)删除前面的注释符号#,并把foobared修改成自己的密码 或者 另起一行 requirepass 自己的密码
⑤设置Redis开机启动
进入:vi /etc/rc.d/rc.local
将bin目录下的/root/home/softwear/redis-6.2.1/bin/redis-server 和etc目录下的/root/home/softwear/redis-6.2.1/etc/redis.conf 添加到文件中
⑥进入redis下的bin目录 cd ~/home/softwear/redis-6.2.1/bin, 启动redis服务redis-server
启动成功!
注意:修改完Redis配置文件后启动时一定要加上配置文件,例如:redis-server redis.conf
⑦redis-server服务启动之后启动后启动客户端 redis-cli
redis-cli -h(地址) 127.0.0.1 -p(端口号) 6379 -a(密码) .....
2.Bloom过滤器安装
下载插件https://download.csdn.net/download/RHHcainiao/88652985
也可以自行下载!
# 1.解压
tar -zxvf v2.2.1.tar.gz
# 2. make一下
cd RedisBloom-2.2.1/
make
2.安装完布隆过滤器后,去redis的配置文件中加载 redisbloom.so文件,在redis.conf中添加配置
#1.打开Redis的conf配置文件
vim redis/redis.conf
添加如下内容:
loadmodule /root/redis-6.2.5/RedisBloom-2.2.5/redisbloom.so
3.验证是否安装且成功配置布隆过滤器,先重启redis,然后使用布隆过滤器的 bf.add命令进行测试,返回1代表布隆过滤器配置完成
# 1.重启进入redis客户端
redis-server /usr/local/redis/redis.conf
redis-cli -h(地址) 127.0.0.1 -p(端口号) 6379 -a(密码) .....
# 2.测试布隆过滤器命令,如果返回1说明布隆过滤器配置成功!
bf.add k1 test
3. 布隆过滤器的基本使用
# 1.清空redis数据库(测试用,慎重!)
flushall
# 2.添加
bf.add k1 helloRedis
# 3.判断是否存在
bf.exists k1 helloRedis
# 4.判断一个不存在的key value
bf.exists k2 helloJava
# 5.批量添加
bf.madd k2 a b c d e
# 6.批量判断
bf.mexists k2 a b c d e
3.Bloom简介
Bloom本质上是一种数据结构,特点是 高效的插入和查询,可用来判断存在或者不存在
直接上代码:
4.SpringBoot集成Bloom
1.添加依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency>
2.编写Bloom帮助类
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
//布隆过滤器
@Component
@Slf4j
public class BloomFilterService {
//Bloom容量100万(根据业务自定义)
private static final int EXPECTED_INSERTIONS = 1000000;
//误差率0.1%
private static final double FPP = 0.001;
//注入过滤器
private BloomFilter<String> bloomFilter;
/**
* 初始化方法
*/
@PostConstruct
public void init() {
log.info("初始化布隆过滤器..............");
//创建一个过滤器,容量100万,误差率0.1% 字符编码UTF-8
bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("UTF-8")), EXPECTED_INSERTIONS, FPP);
}
/**
* 添加元素
* @param value
*/
public void add(String value) {
log.info("向布隆过滤器添加数据....");
bloomFilter.put(value);
}
/**
* 是否存在元素
* @param value
* @return
*/
public boolean mightContain(String value) {
log.info("校验是否存在布隆过滤器.....");
return bloomFilter.mightContain(value);
}
}
3.接口示例编写
调用 localhost:8080/test? ?查看控制台结果
结论:第一次查询数据库后同步向Redis添加key和value向布隆过滤器添加key,第二次先去查布隆过滤器,存在直接从redis获取。
控制台:
向布隆过滤器添加数据....
数据库返回5
校验是否存在布隆过滤器.....
Redis返回5
import com.rh.model.vo.common.Result;
import com.rh.model.vo.common.ResultCodeEnum;
import com.rh.serviceproduct.bloom.BloomFilterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ThreadLocalRandom;
@RestController
public class TestController {
@Autowired
private RedisTemplate<String,String>redisTemplate;
@Autowired
private BloomFilterService bloomFilterService;
@RequestMapping(value="/test")
public Result findAll(){
//这里生成1-10可重复随机数,结果更直观
int randomNumber=0;
for (int i = 0; i < 10; i++) {
randomNumber= ThreadLocalRandom.current().nextInt(1, 11);
}
String findValue=""+randomNumber;//定义一个最终返回值
//1.定义key
String redisKey="Hello:Bloom!"+randomNumber;
//2.判断是否存在Bloom过滤器
if (!bloomFilterService.mightContain(redisKey)) {
//3.如果不存在去查Redis
if (!redisTemplate.hasKey(redisKey)){
//4.如果redis都不在去查库
System.out.println("查询数据库.........");
//5.将数据存入redis,同步存入Bloom
redisTemplate.opsForValue().set(redisKey,findValue);
bloomFilterService.add(redisKey);
System.out.println("数据库返回"+findValue);
}
}else {
//6.key存在Bloom中,从Redis获取数据,防止Bloom误判(概率极低),再判断一遍Redis是否存在key
if (!redisTemplate.hasKey(redisKey)){
System.out.println("查询数据库.........");
redisTemplate.opsForValue().set(redisKey,findValue);
bloomFilterService.add(redisKey);
}
findValue = redisTemplate.opsForValue().get(redisKey);
System.out.println("Redis返回"+findValue);
}
return Result.build(findValue, ResultCodeEnum.SUCCESS);
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!