缓存穿透,缓存雪崩,缓存击透的概念及解决方案

本贴最后更新于 1938 天前,其中的信息可能已经事过景迁

缓存穿透

当客户端频繁地向服务器请求一个缓存中不存在的数据时,服务器会不断查询数据库,数据库可能会因此挂掉。

解决方案

这里有一个简单粗暴的方法。
当查询数据库时,如果结果返回null,这时仍然对其结果进行缓存,但缓存的过期时间很短。

缓存雪崩

在设置缓存时都设置了相同的过期时间,致使缓存同时失效,所有请求将全部转发给数据库,数据库瞬时压力过重,导致雪崩。

解决方案

可以在原有的失效时间基础上增加一个随机值,使得每个key的过期时间分散开,不会集中在同一时间段失效。

缓存击穿

一个存在的key,在缓存过期的那一刻,刚好有大量的请求,大并发的请求会击穿到DB,造成瞬时DB请求量大,压力骤增。

这里的缓存击穿和缓存雪崩看似相同,实际上有一点区别。

* 击穿是针对的某一个key
  • 雪崩是有很多的 key 同时失效

解决方案

在访问key之前,可以采用SETNX(set if not exists)来设置另一个短期的key,通过其来锁住当前key的访问,访问结束就删除该短期key。

``` public String get(key) {
  String value = redis.get(key);
  if (value == null) { //代表缓存值过期
      //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
	  if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表设置成功
           value = db.get(key);
                  redis.set(key, value, expire_secs);
                  redis.del(key_mutex);
          } else {  //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
                  sleep(50);
                  get(key);  //重试
          }
      } else {
          return value;      
      }

}

</senction>
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    286 引用 • 248 回帖 • 62 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...