redis实现布隆过滤器

redis实现布隆过滤器

文档

  1. redis单机安装
  2. redis集群模式 -集群搭建
  3. 布隆过滤器 -Bloom Filter
  4. springboot整合redisson单机模式

官方文档

  1. 官网操作命令指南页面:https://redis.io/docs/latest/commands/?name=get&group=string
  2. Redis cluster specification

下载地址

  1. 官网:https://redis.io/
  2. 下载列表页面:https://download.redis.io/releases/

说明

  1. 版本选择:redis-7.0.0.tar.gz
  2. 下载地址:[https://download.redis.io/releases/redis-7.0.0.tar.gz\](

redis实现布隆过滤器

安装单机版redis
  1. 安装单机版redis参考文档:redis单机安装
springboot整合redisson单机模式
  1. springboot整合redisson单机模式参考文档:springboot整合redisson单机模式
方式一:Redisson RBloomFilter
  1. Redisson 提供了 R BloomFilter,底层用 Bitmap 实现。

  2. 使用示例

    1. 创建IpBlacklistService.java,校验IP黑名单

      java 复制代码
      @Service
      public class IpBlacklistService {
      
          private static final String BLOOM_KEY = "bloom:ip:blacklist";
          private static final long EXPECTED_INSERTIONS = 100_0000L;
          private static final double FALSE_PROBABILITY = 0.01;
      
          private final RedissonClient redissonClient;
      
          public IpBlacklistService(RedissonClient redissonClient) {
              this.redissonClient = redissonClient;
          }
      
          private RBloomFilter<String> getBloomFilter() {
              RBloomFilter<String> filter = redissonClient.getBloomFilter(BLOOM_KEY);
              if (!filter.isExists()) {
                  filter.tryInit(EXPECTED_INSERTIONS, FALSE_PROBABILITY);
              }
              return filter;
          }
      
          public void addToBlacklist(String ip) {
              getBloomFilter().add(ip);
          }
      
          public boolean isBlacklisted(String ip) {
              return getBloomFilter().contains(ip);
          }
      }
    2. 创建IpBlacklistController.java, 提供IP黑名单管理接口,依托Redis布隆过滤器实现黑名单的加入和查询

      java 复制代码
      @RestController
      @RequestMapping("/blacklist")
      public class IpBlacklistController {
      
          private final IpBlacklistService ipBlacklistService;
      
          public IpBlacklistController(IpBlacklistService ipBlacklistService) {
              this.ipBlacklistService = ipBlacklistService;
          }
      
          /**
           * 将 IP 加入黑名单
           *
           * @param ip 待加入黑名单的 IP 地址
           * @return "ok" 表示添加成功
           */
          @PostMapping("/ip")
          public String addIp(@RequestParam("ip") String ip) {
              ipBlacklistService.addToBlacklist(ip);
              return "ok";
          }
      
          /**
           * 判断 IP 是否在黑名单中
           *
           * @param ip 待校验的 IP 地址
           * @return true 可能 blacklisted(存在误判),false 一定不在黑名单
           */
          @GetMapping("/ip/check")
          public boolean checkIp(@RequestParam("ip") String ip) {
              return ipBlacklistService.isBlacklisted(ip);
          }
      }
    3. 调用接口curl命令(windows)

      shell 复制代码
      curl.exe -X POST "http://localhost:8080/redis01/blacklist/ip?ip=192.168.1.100"
      curl.exe "http://localhost:8080/redis01/blacklist/ip/check?ip=192.168.1.100"
方式二:手动用redis实现布隆过滤器
  1. 基本思路

    1. 维护一个长度为 m 的 bit 数组(全 0)
    2. 准备 k 个 彼此独立的 hash 函数,每个把元素映射到 [0, m-1] 的一个下标。
    3. 添加:把元素用 k 个 hash 得到 k 个下标,把这 k 个 bit 都置为 1。
    4. 查询:用同样的 k 个 hash 得到 k 个下标,若全是 1 就说"可能在",有任一是 0 就说"一定不在"。
  2. n、p、m、k的含义

    1. n:要存多少条数据
    2. p:能接受多高的误判率
    3. m:一共用多少 bit 存
    4. k:每个元素用几个 hash(写/查几个 bit)
  3. 参考文档:布隆过滤器 -Bloom Filter,了解n、p、m、k之间的关系

  4. 使用示例

    1. 创建RedisBloomFilter.java,手动实现布隆过滤器逻辑

      java 复制代码
      public class RedisBloomFilter {
      
          private final StringRedisTemplate redisTemplate;
          private final String key;
          private final int bitSize;
          private final int hashCount;
      
          public RedisBloomFilter(StringRedisTemplate redisTemplate, String key, long expectedInsertions, double fpp) {
              this.redisTemplate = redisTemplate;
              this.key = key;
              this.bitSize = optimalNumOfBits(expectedInsertions, fpp);
              this.hashCount = optimalNumOfHashFunctions(expectedInsertions, bitSize);
          }
      
          public void add(String value) {
              for (int i = 0; i < hashCount; i++) {
                  long hash = hash(value, i);
                  long index = (hash & 0x7FFFFFFFFFFFFFFFL) % bitSize;
                  redisTemplate.opsForValue().setBit(key, index, true);
              }
          }
      
          public boolean contains(String value) {
              for (int i = 0; i < hashCount; i++) {
                  long hash = hash(value, i);
                  long index = (hash & 0x7FFFFFFFFFFFFFFFL) % bitSize;
                  if (Boolean.FALSE.equals(redisTemplate.opsForValue().getBit(key, index))) {
                      return false;
                  }
              }
              return true;
          }
      
          private long hash(String value, int seed) {
              long result = 0;
              for (int i = 0; i < value.length(); i++) {
                  result = result * 31 + value.charAt(i) + seed;
              }
              return result;
          }
      
          static int optimalNumOfBits(long n, double p) {
              return (int) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));
          }
      
          static int optimalNumOfHashFunctions(long n, long m) {
              return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));
          }
      }
      • optimalNumOfBits(long n, double p)的作用:在给定预期元素个数 n 和目标误判率 p 时,算出布隆过滤器最少需要多少个 bit(m),使理论误判率不超过 p
      • optimalNumOfHashFunctions(long n, long m) 的作用:在已经定好 bit 数 m 和预期元素个数 n 的前提下,算出使误判率尽量低的 hash 函数个数 k
    2. 创建ManualIpBlacklistService.java,校验IP黑名单

      java 复制代码
      @Service
      public class ManualIpBlacklistService {
      
          private static final String BLOOM_KEY = "bloom:ip:blacklist";
          private static final long EXPECTED_INSERTIONS = 1_000_000L;
          private static final double FALSE_PROBABILITY = 0.01;
      
          private final StringRedisTemplate redisTemplate;
          private volatile RedisBloomFilter bloomFilter;
      
          public ManualIpBlacklistService(StringRedisTemplate redisTemplate) {
              this.redisTemplate = redisTemplate;
          }
      
          private RedisBloomFilter getBloomFilter() {
              if (bloomFilter == null) {
                  synchronized (this) {
                      if (bloomFilter == null) {
                          bloomFilter = new RedisBloomFilter(redisTemplate, BLOOM_KEY, EXPECTED_INSERTIONS, FALSE_PROBABILITY);
                      }
                  }
              }
              return bloomFilter;
          }
      
          public void addToBlacklist(String ip) {
              getBloomFilter().add(ip);
          }
      
          public boolean isBlacklisted(String ip) {
              return getBloomFilter().contains(ip);
          }
      }
    3. 创建ManualIpBlacklistController.java, 提供IP黑名单管理接口,依托Redis布隆过滤器实现黑名单的加入和查询

      java 复制代码
      @RestController
      @RequestMapping("/blacklist/manual")
      public class ManualIpBlacklistController {
      
          private final ManualIpBlacklistService manualIpBlacklistService;
      
          public ManualIpBlacklistController(ManualIpBlacklistService manualIpBlacklistService) {
              this.manualIpBlacklistService = manualIpBlacklistService;
          }
      
          /**
           * 将 IP 加入黑名单(手写布隆过滤器)
           *
           * @param ip 待加入黑名单的 IP 地址
           * @return "ok" 表示添加成功
           */
          @PostMapping("/ip")
          public String addIp(@RequestParam("ip") String ip) {
              manualIpBlacklistService.addToBlacklist(ip);
              return "ok";
          }
      
          /**
           * 判断 IP 是否在黑名单中(手写布隆过滤器)
           *
           * @param ip 待校验的 IP 地址
           * @return true 表示可能 blacklisted(存在误判),false 表示一定不在黑名单
           */
          @GetMapping("/ip/check")
          public boolean checkIp(@RequestParam("ip") String ip) {
              return manualIpBlacklistService.isBlacklisted(ip);
          }
      }
    4. 调用接口curl命令(windows)

      shell 复制代码
      curl.exe -X POST "http://localhost:8080/redis01/blacklist/manual/ip?ip=192.168.1.100"
      curl.exe "http://localhost:8080/redis01/blacklist/manual/ip/check?ip=192.168.1.100"

参考资料

  1. https://www.bilibili.com/video/BV13R4y1v7sP

注意事项

  1. 部分内容由AI生成
  2. 如有不对,欢迎指正!!!
相关推荐
万象.2 小时前
redis持久化:AOF和RDB
数据库·redis·缓存
RANCE_atttackkk2 小时前
Springboot+langchain4j的RAG检索增强生成
java·开发语言·spring boot·后端·spring·ai·ai编程
!chen2 小时前
Redis快速实现布隆过滤器
数据库·redis·缓存
好好研究4 小时前
Spring Boot - Thymeleaf模板引擎
java·spring boot·后端·thymeleaf
编程彩机4 小时前
互联网大厂Java面试:从分布式缓存到消息队列的技术场景解析
java·redis·面试·kafka·消息队列·微服务架构·分布式缓存
xxxmine4 小时前
Redis 持久化详解:RDB、AOF 与混合模式
数据库·redis·缓存
她说..4 小时前
策略模式+工厂模式实现单接口适配多审核节点
java·spring boot·后端·spring·简单工厂模式·策略模式
像少年啦飞驰点、4 小时前
零基础入门 Spring Boot:从“Hello World”到可部署微服务的完整学习路径
java·spring boot·微服务·编程入门·后端开发
甘露s4 小时前
深入理解 Redis:事务、持久化与过期策略全解析
数据库·redis