概述
Redis缓存击穿问题(热key问题)
场景
key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个key在一台Redis服务器上,一台Redis服务器扛不住这么多请求。需要考虑一个问题:缓存被“击穿”的问题。
实际场景
实际场景:大促时,访问量暴增,很多请求都需要请求一个服务开关的 key ,这个key本来在数据库里,但是为了保证速度,将这个 key 放在了Redis中。(这个 key 相当于是一个配置,如果有配置中心,应该放在配置中心,当时是把配置放在了数据库里)
因为有几十万的请求去一台redis服务器上的这个特定 key ,导致Redis 服务器挂掉,请求又打到数据库,之后数据库也挂掉。
这个key就是热key,最终解决的方式是:通过Zookeeper建立了一个统一的配置中心,将 key 的配置拉到本地缓存中,这样大促时,就不会同时有大量请求打到一台Redis服务器上。
解决办法
解决热key的方法:
- 二级缓存,就是将把热key加载到系统的JVM中,存在HashMap中,成为一个本地缓存。
- 备份热key,把这个key,在多个redis上都存一份,不要让key走到同一台redis上。
排查办法
排查热key的方法:
- 人为预测。
- 系统估算。
人为预测
凭借业务经验,进行预估哪些是热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缓存时间短一些,也能节省缓存服务的资源。
最后
以上就是义气小鸽子为你收集整理的Redis常见问题(缓存穿透、热key)的全部内容,希望文章能够帮你解决Redis常见问题(缓存穿透、热key)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复