【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
@Service
public class CacheService {
// 假设布隆过滤器的容错率为0.01,预期元素大小为1000000
private static final double BLOOM_FILTER_FACTOR = 0.01;
private static final int BLOOM_FILTER_EXPECTED_INSERTIONS = 1000000;
private static final BloomFilter<String> bloomFilter = BloomFilter.create(
Funnels.stringFunnel(StandardCharsets.UTF_8),
BLOOM_FILTER_EXPECTED_INSERTIONS,
BLOOM_FILTER_FACTOR);
public String getFromCache(String key) {
// 先检查布隆过滤器,如果不存在,直接返回null,避免缓存穿透
if (!bloomFilter.mightContain(key)) {
return null;
}
// 实际的缓存查询逻辑,这里假设使用了Redis
String value = redisTemplate.opsForValue().get(key);
// 如果缓存没有命中,但布隆过滤器表明可能存在,返回空值""
if (value == null) {
bloomFilter.put(key); // 将key加入布隆过滤器,避免将来的缓存穿透
return "";
}
return value;
}
// 假设的Redis模板,用于缓存操作
@Autowired
private StringRedisTemplate redisTemplate;
}
这个代码示例展示了如何使用布隆过滤器来避免缓存穿透的问题。在getFromCache
方法中,首先检查布隆过滤器是否可能包含指定的键。如果不存在,直接返回null
,避免了缓存的大量查询。如果布隆过滤器表明键存在,才进行实际的缓存查询。如果查询结果为空,我们将该键加入布隆过滤器,并返回一个空值""
,以避免将来对该键的缓存穿透请求。
评论已关闭