使用BloomFilter(布隆过滤器)可解决缓存穿透问题
1.导入依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId>
</dependency>
2.配置redisson
@Configuration
public class RedissonConfig {//从application.properties中获取spring.redis.host配置@Value("${spring.redis.host}")private String redisHost;//从application.properties中获取spring.redis.port配置@Value("${spring.redis.port}")private int redisPort;//从application.properties中获取bloomfilter.v1参数@Value("${bloomfilter.v1}")private Long v1;//从application.properties中获取bloomfilter.var3容错率参数@Value("${bloomfilter.var3}")private double var3;//将redissonClient配置为springBean后可以重新根据自己需要配置loomFilter@Beanpublic RedissonClient redissonClient(){Config config = new Config();config.useSingleServer().setAddress("redis://"+redisHost+":"+redisPort);return Redisson.create(config);}//配置默认的loomFilter@Beanpublic RBloomFilter<String> bloomFilter(){RBloomFilter<String> bloomFilter=redissonClient().getBloomFilter("bloom-filter");bloomFilter.tryInit(v1,var3);return bloomFilter;}
}
3.初始化bloomfilter内容
@Component
public class StartUser implements ApplicationRunner{@Autowiredprivate UserMapper userMapper;@Autowiredprivate RedissonConfig redissonConfig;private RBloomFilter<String> rbloomFilter;@PostConstructpublic void init(){rbloomFilter = redissonConfig.bloomFilter();}@Overridepublic void run(ApplicationArguments args) {List<User> users = userMapper.selectList();value.stream().map(User->{rbloomFilter.add(User.getUserId());return null;}).collect(Collectors.toList()); }
}
4.使用,判断是否存在,不存在不让查询数据库
@Service
public class UserServiceImpl implements UserService{@Autowiredprivate UserMapper userMapper;@Autowiredprivate RedissonConfig redissonConfig;private RBloomFilter<String> rbloomFilter;@PostConstructpublic void init(){rbloomFilter = redissonConfig.bloomFilter();}public ApiRes getUserById(String userId){//布隆过滤器拦截boolean contains = rbloomFilter.contains(userId);if (!contains){return ApiRes.fail(407,"userId不存在!");}User user=userMapper.getUserById(userId);return ApiRes.success(user);}
}