缓存击穿、缓存穿透、缓存雪崩

  • 缓存击穿

    • 当某一个缓存失效时候,瞬时并发或请求量很大大,由于缓存失效,直接穿透到数据库查询。

    • 解决办法:单机情况可以使用synchronized,分布式情况设置一个redis分布式锁(原生的是setnx对应redisson),注意使用锁的时候,最好加上超时时间。reentrantlock的定时锁tryLock(long, TimeUnit)或redis的超时时间

String get(String key) {  
   String value = redis.get(key);  
   if (value  == null) {  
    if (redis.setnx(key_mutex, "1")) {  
        // 3 min timeout to avoid mutex holder crash  
        redis.expire(key_mutex, 3 * 60)  
        value = db.get(key);  
        redis.set(key, value);  
        redis.delete(key_mutex);  
    } else {  
        //其他线程休息50毫秒后重试  
        Thread.sleep(50);  
        get(key);  
    }  
  }  
}  
  • 缓存穿透

    • 频繁的查询一个不存在的值,故意的攻击数据库

    • 解决办法:如果查询结果为空的时候,仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟,更新数据的时候,刷新缓存。方法二:采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。笔者认为采用过滤器的方法,首先要知道值的范围,才能针对性的设置bitmap。

  • 缓存雪崩

    • 多个缓存对象,设置的过期时间一致,在同一时间过期,大量查询数据库。

    • 解决办法:使用随机值的方式,设置缓存时间,比如50分钟到60分钟之间随机数

你可能感兴趣的:(java,缓存)