Redis常见问题(缓存穿透、热key)

Redis缓存击穿问题(热key问题)

场景

key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个key在一台Redis服务器上,一台Redis服务器扛不住这么多请求。需要考虑一个问题:缓存被“击穿”的问题。

实际场景

实际场景:大促时,访问量暴增,很多请求都需要请求一个服务开关的 key ,这个key本来在数据库里,但是为了保证速度,将这个 key 放在了Redis中。(这个 key 相当于是一个配置,如果有配置中心,应该放在配置中心,当时是把配置放在了数据库里)

因为有几十万的请求去一台redis服务器上的这个特定 key ,导致Redis 服务器挂掉,请求又打到数据库,之后数据库也挂掉。

这个key就是热key,最终解决的方式是:通过Zookeeper建立了一个统一的配置中心,将 key 的配置拉到本地缓存中,这样大促时,就不会同时有大量请求打到一台Redis服务器上。

解决办法

解决热key的方法:

  1. 二级缓存,就是将把热key加载到系统的JVM中,存在HashMap中,成为一个本地缓存。
  2. 备份热key,把这个key,在多个redis上都存一份,不要让key走到同一台redis上。

排查办法

排查热key的方法:

  1. 人为预测。
  2. 系统估算。

人为预测

凭借业务经验,进行预估哪些是热key。比如某商品在做秒杀,那这个商品的key就可以判断出是热key。缺点很明显,并非所有业务都能预估出哪些key是热key。

系统估算

系统在操作redis之时,进行数据统计。可以加入一行代码,打日志来判断,或者是用Redis的命令。

Redis缓存穿透问题

场景

缓存穿透,就是如果从数据库中查出的是null,存入Redis的就也是null,然后如果有人不停的查,就相当于是不停的查数据库,(因为是null,所以跳过了或者是透过了Redis),请求的多了可能就把数据库弄崩了。

解决办法

解决的办法,就是在查询数据库后,判断一下,如果为null,也存进去,赋值空集合。(空集合不是null)
可以设置这个key的存活时间短一点。

List<Coupon> list = null;
//加缓存
String couponCacheKey = TIME_LIMIT_LIST_KEY_DAO ;
if (xzCacheUtil.getString(couponCacheKey) != null) {
    //获取list,并将str转换为对象
    list = JSON.parseArray(xzCacheUtil.getString(couponCacheKey), Coupon.class);
}
else{
    //如果不存在,重新查询并存入缓存
    lList = Dao.queryInfo();
    if(list == null){
        list = new ArrayList<>();
    }
    xzCacheUtil.setStringEx(couponCacheKey, JSON.toJSONString(list), 5L, TimeUnit.MINUTES);
}

Redis缓存雪崩问题

场景

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决办法

一般是采取不同分类 key,缓存不同周期。在同一分类中的 key,加上一个随机因子。这样能尽可能分散缓存过期时间,而且,热门的key缓存时间长一些,冷门的key缓存时间短一些,也能节省缓存服务的资源。

发布了67 篇原创文章 · 获赞 32 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43751710/article/details/103554100