Redis学习之性能优化

多级缓存架构

在这里插入图片描述

Redis常见问题

缓存穿透

说明

缓存穿透是指查询一个根本不存在的数据,缓存和数据库都不会命中,如果数据库查不到则不写入缓存.这样将导致不存在的数据的每次请求都要查询数据库,失去了缓存保护后端数据库的意义.

造成原因

1.自身业务代码或数据出现问题.
2.一些恶意攻击、爬虫等造成大量空命中.

解决方案
  • 缓存空对象
// 去数据库获取数据等时候,如果为null,就塞一个空对象到缓存,防止连续访问,还得设置时间,如果这个key有了真实的值后再去获取
String get(String key) { 
   // 从缓存中获取数据 
   String cacheValue = cache.get(key); 
   // 缓存为空
   if (StringUtils.isBlank(cacheValue)) { 
     // 从存储中获取 
     String storageValue = storage.get(key); 
     cache.set(key, storageValue);
     // 如果存储数据为空, 需要设置一个过期时间(300秒)
      if (storageValue == null) { 
        cache.expire(key, 60 * 5); 
      } 
     return storageValue; 
   } else {
     // 缓存非空 
     return cacheValue; 
   } 
 }
  • 布隆过滤器
    在这里插入图片描述
    对于恶意攻击,向服务器请求大量不存在的数据导致缓存击穿,还可以使用布隆过滤器先做一次过滤,不让请求再往后端发送.核心:当布隆过滤器说某个值存在时,不一定存在;当它说这个值不存在时一定不存在.
// 布隆过滤器
1.首先会将缓存中的key通过一系列的hash算法,找到布隆过滤器对应数组的索引,标记'1'.
2.get()数据时,也会将key进行一系列的hash算法,如果算出来的值,都是'1',说明这个值可能存在.如果有不为'1'的那就一定不存在.
3.不同担心hash冲突,布隆过滤器的数组会非常大,通常是百亿
4.相较于第一种往缓存中放空对象的方式,布隆过滤器更加的节省空间.
总结

在这里插入图片描述

缓存击穿

说明

指缓存中没有数据,数据库中有数据。一般是并发用户多,缓存时间刚好到期,缓存中读不到数据,直接去数据库读取,造成数据库压力大。

解决方案
  • 设置热点数据永远不过期。
  • 缓存加锁重建
    代码里加互斥锁,缓存中没数据,第一个进入的线程获取锁从数据库读取数据,读到后再放入缓存,其他线程等待,再重新去缓存中获取。
// 伪代码 -- 热点缓存key重建优化
String get(String key) { 
  // 从缓存中获取数据 
  String cacheValue = cache.get(key); 
  // 缓存为空 
  if (StringUtils.isBlank(cacheValue)) { 
    if(lock){
       // 从存储中获取
    String storageValue = storage.get(key); 
    cache.set(key, storageValue); 
    }
   // 释放锁
   unlock();
}else{
     // 睡眠1秒,再去缓存获取
   Thread.sleep(1000);
   get(key);
  }
 ...

缓存雪崩

说明

指缓存中大批数据过期,而查询数量巨大,导致数据库压力大,甚至宕机。和缓存击穿不同的是,缓存击穿是并发查同一数据。缓存雪崩时不同数据都过期。

解决方案
  • 设置热点数据永不过期。
  • 缓存数据的过期时间随机,防止同一时间出现大量数据过期。

缓存数据库读写不一致问题

说明

在大并发下,同时操作数据库和缓存会存在数据不一致性.

造成原因
  • 双写不一致
    在这里插入图片描述
  • 读写不一致
    在这里插入图片描述
解决方案
  • 如果业务上能容忍,就加上缓存过期时间,可以解决大部分业务对于缓存的需求。
  • 如果无法容忍数据不一致,可以加读写锁保证并发读写或写写的时候按顺序排好队,读读相当无锁。
  • 使用阿里开源的canal通过监听数据库的binlog日志及时的去修改缓存,但是引入中间件增加系统复杂性.

Redis淘汰策略

  • 被动删除
    当读写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key.
  • 主动删除
    由于惰性删除策略无法保证冷数据被及时删除.所以redis会定期主动淘汰一批已经过期的key.
  • 内存超过maxmemory限定时,触发清理策略
// 4.0之前一共6种,4.0之后一共8种.
// 针对设置了过期时间的key做处理
1.volatile-ttl
在筛选时,会针对设置了过期时间的健值对,根据过期时间的先后进行删除,越早过期的越先被删除.
2.volatile-random
针对设置了过期时间的健值对随机删除.
3.volatile-lru
默认机制,针对设置了时间的健值对,会优先删除最近最少使用的key.(以最近时间为参考)
4.volatile-lfu
针对设置了时间的健值对,会优先删除最近访问次数最少的key.(以次数为参考)
// 针对所有的key做处理
5.allkeys-random
从所有键值对中随机选择并删除数据
6.allkeys-lru
所有健值对中,会优先删除最近最少使用的key.(以最近时间为参考)
7.allkeys-lfu
所有健值对中,会优先删除最近访问次数最少的key.(以次数为参考)
// 不处理
8.noeviction
不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息,这时只能读数据,不能写.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值