WEB应用缓存,在高并发多请求的情况下的缓存"击穿"问题

什么是缓存击穿?

答: 一般情况下,某些大负载的系统为了提供性能,会使用缓存服务,一般的做法是将一些不经常改变的内容缓存到另外的服务中。然后在过期之后进行自动从数据后端更新数据。这里的问题就在于,过期这个时间点。假如在过期这个时间点,突然有很多的数据请求,缓存服务发现数据过期,就会从后端查询数据,导致后端直接崩溃。也就是这层缓存失效了!

通常的解决思路

答:这里主要是在缓存服务方面做一些保护措施,防止过多的请求直接发往后端。通常的做法是对这么多请求进行阻塞,然后仅适用少量请求去更新数据,被阻塞的请求会进行重试,直到数据被更新完成。具体是通过设置互斥量进行设置数据更新请求的数量,在redis中可以使用 SETNX ,这样,保证只有少量的数据更新请求!

参考代码

  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;      
          }
  }
如果你有更好的做法,欢迎私信或讨论区进行交流~

猜你喜欢

转载自blog.csdn.net/hpulfc/article/details/80987850