缓存优化

1.1穿透优化

        缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,由于每次请求都要到存储层去查询,导致存储层负载加大,造成存储层宕机。

1.1.2缓存空对象

        当客户端查询数据不存在时,将空对象保留到缓存中,之后在访问这个数据将会从缓存中获取,有效的减轻了存储层的压力。伪代码如下:

String cacheValue = redis.get(key)
if(isNull(cacheValue)){
    String dbValue=mysql.get(key);
    redis.set(key,dbValue);
    if(dbValue == null){
      redis.expire(key,expireTime);
    }
    return dbValue;
}else{
   return cacheValue;
}

        缓存空对象需要更多的缓存空间,而且会出现数据不一致的情况。

1.1.2布隆过滤器

        在访问缓存层和存储层之前,将存在的key用布隆过滤器提前保存起来。bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中。和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一个标志,用来判断key是否在集合中,可以利用Redis的Bitmaps实现布隆过滤器。布隆过滤器的相关知识可以参考:https://www.cnblogs.com/liyulong1982/p/6013002.html

1.2雪崩优化

        由于在同一时刻出现大面积的缓存过期,所有原本应该访问缓存的请求都去查询数据库了,造成存储层负载巨大压力,严重导致数据库宕机。

1.2.1加锁

        利用加锁的方式保证不会有大量的并发请求对数据库一次性进行读写,从而避免缓存失效时大量的并发请求查询数据库。伪代码如下:

String get(String key){
    //从redis中获取数据
    String value = redis.get(key);
    if(value=null){
      //只允许一个线程重构缓存
      String mutexKey= "mutex:key:"+key;
      if(redis.set(mutexKey,"1","ex 180","nx")){
        //从数据库获取数据
         value = db.get(key);
         //写redis,设置过期时间
         redis.setex(key,timeout,value);
         //删除互斥锁
         redis.delete(mutexKey);
      }else{
          Thead.sleep(50);
          get(key);
      }
    }
  return value;
}
1.2.2设置不过期

        该方法就是缓存不设置过期时间,另外可以为value设置一个逻辑过期时间,当发现超过逻辑时间,会使用单独的线程去数据库重新获取数据。该方法会产生数据不一致的情况。伪代码如下:

String get(String key){
    V v = redis.get(key);
    String value = v.getValue();
    //获取逻辑过期时间
    long logicTimeout = v.getLogicTimeout();
    //如果逻辑过期时间小于当前时间,开始重新获取数据
    if(v.logicTimeout<=System.currentTimeMillis()){
      String mutexKey = "mutex:key:"+key;
      if(redis.set(mutexKey,"1","ex 180","nx")){
         theadPool.execute(new Runnable(){
              public void run(){
                   String dbValue = db.get(key);
                   redis.set(key,(dbvalue,newLogicTimeout));
                   redis.delete(mutexKey);
              }
         })
      }
    }
     return value;
}

1.3参考资料

        《Redis开发与运维》

转载于:https://my.oschina.net/wuchanghao/blog/1827257

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值