缓存穿透、缓存雪崩、缓存击穿的原因及解决方案

缓存穿透、缓存雪崩、缓存击穿的原因及解决方案

  • 缓存穿透
是指查询一个一定不存在的数据,这将导致这个不存在的数据每次请求都要DB去查询,失去了缓存的一样。在流量大的时候,可能DB就挂了。
解决方案
    有很多种方法可以有效地解决缓存穿透问题:
    1.对空值做缓存;
    2.设置key的规则;
    3.采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
  • 缓存雪崩
是指我们设置缓存时采用了相同的过期时间,导致缓存在某一时间同时失效,请求全部到DB,DB瞬时压力过重雪崩。

解决方案
    可以设置一个失效时间的随机数,这样可以让缓存的过期时间重复率降低,从而导致雪崩。

 

 

  • 缓存击穿
我们设置了过期时间的key,如果这些key可能在某些时间点被超高并发地访问,恰好在这个时间点某个key缓存过期,有大量的并发请求过来,这些请求发现缓存过期就会从后端DB加载数据并重新set到缓存中,这个时间大并发的请求可能会瞬间把后端DB压垮。

解决方案
    我们的目标是:尽量少的线程去查询数据重新set到缓存中并且要满足数据一致性;
    1.使用互斥锁:


        实现方式如下:

public void get(String key) {
        String value = jedis.get(key);
        if (value == null) {
            if (jedis.setnx(key_nx, "1")) {
                jedis.expire(key_nx, 3 * 60);
                value = db.get(key);
                jedis.set(key, value);
                jedis.delete(key_nx);
            } else {
                //其他线程休息50毫秒后重试  
                Thread.sleep(50);
                get(key);
            }
        }
    }

 

    



posted @ 2018-11-27 20:33  胡金水  阅读(1376)  评论(0编辑  收藏  举报