Redis中间件,我们主要是用来做缓存,缓解数据库的访问压力,我们搭建的是redis集群
在一个风和日丽的下午,突然收到运维的报警信息 运维:小李,你们使用的redis中间件所在的服务器,有大量的流量流出,宽带快要占满了,网卡都冒烟了,严重影响其他服务,快速排查解决下,如果一时半会解决不了,我们只能kill掉redis的进程,避免影响其他服务小李:我们立刻排查,有需要协助的,请你们帮忙
我们redis使用的是集群,三主三从,怎么才有一台流量这么大?大概率我估计是遇到了大key、热key,大key是存储的数据量大,热key访问频率高,分布还不均匀,才能导致单台机器流量非常大
先介绍下 热key、大key,让大家有个了解
在使用Redis的过程中,如果未能及时发现并处理大Key与热Key,可能会导致服务性能下降、用户体验变差,甚至引发大面积故障。
通常以Key的大小和Key中成员的数量来综合判定,例如:
通常以其接收到的Key被请求频率来判定,例如:
上述例子中的具体数值仅供参考,在实际业务中,您需要根据Redis的实际业务场景进行综合判断。
未正确使用Redis、业务规划不足、无效数据的堆积、访问量突增等都会产生大Key与热Key
预期外的访问量陡增,如突然出现的爆款商品、访问量暴涨的热点新闻、直播间某主播搞活动带来的大量刷屏点赞、游戏中某区域发生多个工会之间的战斗涉及大量玩家等。
通过上面的介绍,应该对大key、热key,有个了解了,那下面介绍下,我们排查问题的过程
redis4.0版本以上提供了分析大key、热key的分析工具,前提是:内存策略修改为**LFU
**算法
# 分析统计热key
redis-cli --hotkeys
# 分析统计大key
redis-cli --bigkeys
以上两个命令,就可以分析线出线上的热key、大key。也是通过 scan 完成的,可能会对节点造成阻塞,同时bigkeys只能计算每种数据结构的 top1,如果有些数据结构有比较多的 Bigkey是查找不出来的,如下:
此方案暂时放弃,主要怕对节点造成阻塞
从业务角度出发,我们的系统有链路跟踪,使用的是pinpoint,通过pinpoint查看最近这段时间请求量高、响应慢的接口,找出top靠前的接口,找到接口对应的代码,进行分析,查找这些接口哪里调用了redis,使用的key,然后对key进行查看
通过接口代码分析,发现其中一个接口,for循环里面调用redis,获取值,伪代码如下:
public List getData(){
/**
* 1、通过条件分页查询数据
* 2、对查询出来的数据,for循环去查询redis 的数据,然后对查询出来的数据,进行转换,再组装数据
*
*/
//查询业务数据
List<AccessLogEntity> list = new ArrayList<>();
for (AccessLogEntity accessLog : list) {
String str = redisTemplate.opsForValue().get("key");
//json字符转换为对象
//对list的数据进行匹配 关联
// 组装数据
}
return list;
}
代码分析:
通过以上两个修改,发布线上,持续观察,运维反馈:流量降下来了,服务正常了
通过项目代码分析,这并不存在热key,是人为放在分页循环里面导致的,所以不考虑热key的问题,只需要把大key优化掉即可
我们使用hash替换String,并且key拆分为多个hash key,并确保每个Key的成员数量在合理范围
通过这个事故,也让我深究大key、热key的解决方案
在Redis集群架构中,由于热Key的迁移粒度问题,无法将请求分散至其他数据分片,导致单个数据分片的压力无法下降。此时,可以将对应热Key进行复制并迁移至其他数据分片,例如将热Key foo复制出3个内容完全一样的Key并名为foo2、foo3、foo4,将这三个Key迁移到其他数据分片来解决单个数据分片的热Key压力。
当出现热 Key
以后,把热 Key
加载到系统的 JVM
中。后续针对这些热 Key
的请求,会直接从 JVM
中获取,而不会走到 Redis
层。这些本地缓存的工具很多,比如 Ehcache
,或者 Google Guava
中 Cache
工具,或者直接使用 HashMap
作为本地缓存工具都是可以的。
这里有两个缺点:
Key
进行本地缓存,需要防止本地缓存过大,影响系统性能;Redis
集群数据的一致性问题。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。