【Redis】Redis布隆过滤器

缓存击穿介绍

什么是缓存击穿

我们通常使用redis作为数据缓存,当请求进来时先通过key去redis缓存查询,如果缓存中数据不存在,需要去查询数据库的数据。当数据库和缓存中都不存在的数据来查询时候,请求都打在数据库的请求中。如果这种请求量很大,会给数据库造成更大的压力进而影响系统的性能。
在这里插入图片描述

解决这类问题的方法

方法一:当DB和redis中都不存在key,在DB返回null时,在redis中插入<key,null,expireTime>key再次请求时,redis直接返回null,而不用再次请求DB。

方法二:使用redis提供的redisbloom,同样是将存在的key放入到过滤器中。当请求进来时,先去过滤器中校验是否存在,如果不存在直接返回null

在这里插入图片描述

过滤器用途

  1. 判断过滤器中是否存在该数据进而减少没有必要的数据库请求

引入redisbloom

官方文档上面提供docker安装redisbloom和下载编译的方式引入redisbloom的模块。
下面介绍一下编译的方式来引入redisbloom模块

git clone https://github.com/RedisLabsModules/redisbloom.git
cd redisbloom
make # 编译redisbloom

启动redis-server时引入redisbloom模块

./redis-5.0.4/src/redis-server --loadmodule ./redisbloom/rebloom.so

在redis.conf中配置

loadmodule ../redisbloom/rebloom.so

bloom 指令

bf.reserve {key} {error_rate} {size}

127.0.0.1:6379> bf.reserve userid 0.01 100000
OK
  • 描述:
    创建一个空的布隆过滤器,并设置一个期望的错误率和初始大小。{error_rate}过滤器的错误率在0-1之间,如果要设置0.1%,则应该是0.001。该数值越接近0,内存消耗越大,对cpu利用率越高。

bf.add {key} {item}

bf.madd {key} {item} [item…]

  • 描述:往过滤器中添加元素。如果key不存在,过滤器会自动创建。
127.0.0.1:6379> bf.add userid '101310299'
(integer) 1
127.0.0.1:6379> bf.madd userid '101310299' '101310366' '101310211'
1) (integer) 0
2) (integer) 1
3) (integer) 1

bf.exists {key} {item}

bf.mexists {key} {item} [item…]

  • 描述:判断过滤器中是否存在该元素,不存在返回0,存在返回1。
127.0.0.1:6379> bf.exists userid '101310299'
(integer) 1
127.0.0.1:6379> bf.mexists userid '101310299' '10saa' '101310211'
1) (integer) 1
2) (integer) 0
3) (integer) 1

java API

java程序员可以通过RedisBloom类库提供的API实现高性能布隆过滤器

maven引入类库
	<dependency>
      <groupId>com.redislabs</groupId>
      <artifactId>jrebloom</artifactId>
      <version>1.0.1</version>
    </dependency>
    <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.0.0</version>
        </dependency>
API使用
public class RedisBloomDemo {
    public static void main(String[] args) {
        String userIdBloomKey = "userid";
        // 创建客户端,jedis实例
        Client client = new Client("localhost", 6378);
        // 创建一个有初始值和出错率的过滤器
        client.createFilter(userIdBloomKey,100000,0.01);
        // 新增一个<key,value>
        boolean userid1 = client.add(userIdBloomKey,"101310222");
        System.out.println("userid1 add " + userid1);

        // 批量新增values
        boolean[] booleans = client.addMulti(userIdBloomKey, "101310111", "101310222", "101310222");
        System.out.println("add multi result " + booleans);

        // 某个value是否存在
        boolean exists = client.exists(userIdBloomKey, "101310111");
        System.out.println("101310111 是否存在" + exists);

        //某批value是否存在
        boolean existsBoolean[] = client.existsMulti(userIdBloomKey, "101310111","101310222", "101310222","11111111");
        System.out.println("某批value是否存在 " + existsBoolean);
    }
}

遇到一个坑

jrebloom项目中使用的jedis是3.0.0-m1,而自己项目中引入的jedis是2.9.0
而且发现3.0.0以上版本有些方法找不到了。例如set(String key, String value, String nxxx, String expx, long time)
因此如果要在项目中使用redisbloom,要注意jedis的版本信息。

参考文献:

https://oss.redislabs.com/redisbloom/Bloom_Commands/
https://github.com/RedisBloom/JReBloom
https://blog.csdn.net/zeb_perfect/article/details/54135506

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值