Redis缓存穿透

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis缓存穿透

缓存穿透:在这种情况下,缓存服务器找不到指定key的有效缓存信息,同时下游的数据库也查询不到对应的数据,这就造成了业务系统的无效请求全部落在了数据库上,缓存服务器完全没有起到作用。


解决方案:

1)缓存空数据,查询返回的数据为空,仍把这个结果进行缓存

优点:简单


缺点:消耗内存,可能发生不一致问题


2)布隆过滤器

优点:内存占用较少,没有多余key


缺点:实现复杂,存在误判


布隆过滤器是一种数据结构,用于快速检索一个元素是否可能存在于一个集合(bit数组)中。


它的基本原理是利用多个哈希函数,将一个元素映射成多个位,然后将这些位设置成1。当查询一个元素时,如果这些位都被设置成1,则认为元素可能存在于集合中,否则肯定不存在。


所以,布隆过滤器可以准确判断一个元素是否肯定不存在,但是因为hash冲突的原因,所以它没办法判断一个元素是否一定存在。只能判断可能存在。


误判率:如果判断元素存在,可能存在误判。跟数组长度有关,数组长度越长,误判率越低,但是内存消耗增大。数组长度越小,误判率越高,内存消耗越低。一般保证误判率在5%以内可以没满足需要。


流程:



使用步骤:


Java中可以使用第三方库来实现布隆过滤器,常见的有Google Guava库和Apache Commons库以及Redis


Guava

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
public class BloomFilterExample {
    public static void main(String[] args) {
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringsFunctor(), 10, 0.01); 
        // 插入元素
        bloomFilter.put("Hollis");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Hollis"));   // true
        System.out.println(bloomFilter.mightContain("王星星"));  // false
    }
}

Apache Commons

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.BloomFilter;
import org.apache.commons.collections4.functors.HashTransformer;
public class BloomFilterExample {
    public static void main(String[] args) {
        // 创建布隆过滤器,预测插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = new BloomFilter<>(HashFunctionIdentity.hashFunction(String::hashCode), 100, 0.01);
        bloomFilter.put("Hollis");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Hollis"));   // true
        System.out.println(bloomFilter.mightContain("王星星"));  // falses
        // 清除所有已知条目
        for (String key : bloomFilter.keys()) {
            bloomFilter.remove(key);
        }
    }
}

3) Redis中可以通过Bloom模块来使用,使用Redisson可以:

//创建 Config 对象,设置单个服务器地址
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379/");
//创建 RedissonClient 对象
RedissonClient redisson = Redisson.create(config);
//获取 RBloomFilter 对象
RBloomFilter<String> bloomFilter = redisson.getBlobStore("myfilter").getOrInit(new StringSerializer<>());
//初始化布隆过滤器,参数分别为容量(max elements)和误识别率(false positive rate)
bloomFilter.tryInit(100, 0.01);
bloomFilter.add("Hollis");
bloomFilter.add("666");
bloomFilter.add("八股文");
System.out.println(bloomFilter.contains("Hollis"));
System.out.println(bloomFilter.contains("王巨星"));
//关闭客户端
redisson.shutdown();

或者Jedis

Jedis jedis = new Jedis("localhost");
jedis.bfCreate("myfilter", 100, 0.01);
jedis.bfAdd("myfilter", "Hollis");
jedis.bfAdd("myfilter", "666");
jedis.bfAdd("myfilter", "八股文");
System.out.println(jedis.bfExists("myfilter", "Hollis"));
System.out.println(jedis.bfExists("myfilter", "王星星"));
jedis.close();


相关文章
|
5月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
3月前
|
缓存 数据库连接 数据库
缓存三剑客(穿透、击穿、雪崩)
缓存穿透指查询数据库和缓存中都不存在的数据,导致请求直接冲击数据库。解决方案包括缓存空对象和布隆过滤器。缓存击穿是大量请求访问同一个失效的热点数据,使数据库瞬间压力剧增,解决方法有提前预热、设置永不过期、加锁限流等。缓存雪崩是大量key同时失效,导致所有请求直达数据库,可通过引入随机过期时间缓解。三者分别对应单点爆破、全面崩塌等问题,需根据场景选择合适策略优化系统性能与稳定性。
220 0
|
19天前
|
存储 缓存 NoSQL
Redis专题-实战篇二-商户查询缓存
本文介绍了缓存的基本概念、应用场景及实现方式,涵盖Redis缓存设计、缓存更新策略、缓存穿透问题及其解决方案。重点讲解了缓存空对象与布隆过滤器的使用,并通过代码示例演示了商铺查询的缓存优化实践。
108 1
Redis专题-实战篇二-商户查询缓存
|
5月前
|
缓存 NoSQL Java
Redis+Caffeine构建高性能二级缓存
大家好,我是摘星。今天为大家带来的是Redis+Caffeine构建高性能二级缓存,废话不多说直接开始~
732 0
|
19天前
|
缓存 NoSQL 关系型数据库
Redis缓存和分布式锁
Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列和内存数据库。其典型应用包括缓解关系型数据库压力,通过缓存热点数据提高查询效率,支持高并发访问。此外,Redis 还可用于实现分布式锁,解决分布式系统中的资源竞争问题。文章还探讨了缓存的更新策略、缓存穿透与雪崩的解决方案,以及 Redlock 算法等关键技术。
|
3月前
|
缓存 数据库
如何解决缓存穿透?
对请求增加校验机制,如ID格式和位数校验,避免无效请求;缓存空值或特殊值防止缓存穿透;使用布隆过滤器拦截不存在的请求,减轻数据库压力。
42 0
|
5月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
194 32
|
5月前
|
缓存 NoSQL Java
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
112 5
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
|
7月前
|
缓存 NoSQL Java
Redis应用—8.相关的缓存框架
本文介绍了Ehcache和Guava Cache两个缓存框架及其使用方法,以及如何自定义缓存。主要内容包括:Ehcache缓存框架、Guava Cache缓存框架、自定义缓存。总结:Ehcache适合用作本地缓存或与Redis结合使用,Guava Cache则提供了更灵活的缓存管理和更高的并发性能。自定义缓存可以根据具体需求选择不同的数据结构和引用类型来实现特定的缓存策略。
405 16
Redis应用—8.相关的缓存框架
|
7月前
|
缓存 监控 NoSQL
Redis--缓存击穿、缓存穿透、缓存雪崩
缓存击穿、缓存穿透和缓存雪崩是Redis使用过程中可能遇到的常见问题。理解这些问题的成因并采取相应的解决措施,可以有效提升系统的稳定性和性能。在实际应用中,应根据具体场景,选择合适的解决方案,并持续监控和优化缓存策略,以应对不断变化的业务需求。
1313 29