【转】缓存击穿的解决方案

缓存击穿:
缓存击穿对应的一般都是热点数据。key对应的数据存在,但是到了过期时间,此时如果出现高并发情况,有大量并发请求过来,因为没有缓存数据,所以都回去访问数据库并回设缓存,这时候高并发就可能瞬间把数据库压垮。

解决方案:

使用互斥锁。算是很常用的方式。
简单来说就是在缓存失效的时候不立刻去数据库拿数据,而是先使用缓存中某些带有成功操作后有返回值的操作去set一个mutex key,比如redis的setnx或者memcache的add。当操作成功返回时,再去数据库拿数据并回设缓存。否则就重试整个get缓存方法。

setnx,即只有不存在的时候会设置,可以用来实现加锁效果。

redis代码:

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;      
          }
 }

memcache 代码:

if (memcache.get(key) == null) {  
    // 3 min timeout to avoid mutex holder crash  
    if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {  
        value = db.get(key);  
        memcache.set(key, value);  
        memcache.delete(key_mutex);  
    } else {  
        sleep(50);  
        retry();  
    }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值