达到物理网卡上限,突然几十万的请求访问Redis的某个key如何解决


达到物理网卡上限,突然几十万的请求访问Redis的某个key如何解决

文章插图
 
热Key问题所谓热key问题就是 , 突然有几十万的请求去访问redis上的某个特定key 。那么 , 这样会造成流量过于集中 , 达到物理网卡上限 , 从而导致这台redis的服务器宕机 。
那接下来这个key的请求 , 就会直接怼到你的数据库上 , 导致你的服务不可用 。
怎么发现热key方法一:凭借业务经验 , 进行预估哪些是热key
其实这个方法还是挺有可行性的 。比如某商品在做秒杀 , 那这个商品的key就可以判断出是热key 。缺点很明显 , 并非所有业务都能预估出哪些key是热key 。
方法二:在客户端进行收集
这个方式就是在操作redis之前 , 加入一行代码进行数据统计 。那么这个数据统计的方式有很多种 , 也可以是给外部的通讯系统发送一个通知信息 。缺点就是对客户端代码造成入侵 。
方法三:在Proxy层做收集
有些集群架构是下面这样的 , Proxy可以是Twemproxy , 是统一的入口 。可以在Proxy层做收集上报 , 但是缺点很明显 , 并非所有的redis集群架构都有proxy 。
达到物理网卡上限,突然几十万的请求访问Redis的某个key如何解决

文章插图
 
方法四:用redis自带命令
(1)monitor命令 , 该命令可以实时抓取出redis服务器接收到的命令 , 然后写代码统计出热key是啥 。当然 , 也有现成的分析工具可以给你使用 , 比如redis-faina 。但是该命令在高并发的条件下 , 有内存增暴增的隐患 , 还会降低redis的性能 。
(2)hotkeys参数 , redis 4.0.3提供了redis-cli的热点key发现功能 , 执行redis-cli时加上–hotkeys选项即可 。但是该参数在执行的时候 , 如果key比较多 , 执行起来比较慢 。
方法五:自己抓包评估
Redis客户端使用TCP协议与服务端进行交互 , 通信协议采用的是RESP 。自己写程序监听端口 , 按照RESP协议规则解析数据 , 进行分析 。缺点就是开发成本高 , 维护困难 , 有丢包可能性 。
以上五种方案 , 各有优缺点 。根据自己业务场景进行抉择即可 。那么发现热key后 , 如何解决呢?
如何解决目前业内的方案有两种
(1)利用二级缓存
比如利用ehcache , 或者一个HashMap都可以 。在你发现热key以后 , 把热key加载到系统的JVM中 。
针对这种热key请求 , 会直接从jvm中取 , 而不会走到redis层 。
假设此时有十万个针对同一个key的请求过来,如果没有本地缓存 , 这十万个请求就直接怼到同一台redis上了 。
现在假设 , 你的应用层有50台机器 , OK , 你也有jvm缓存了 。这十万个请求平均分散开来 , 每个机器有2000个请求 , 会从JVM中取到value值 , 然后返回数据 。避免了十万个请求怼到同一台redis上的情形 。
(2)备份热key
这个方案也很简单 。不要让key走到同一台redis上不就行了 。我们把这个key , 在多个redis上都存一份不就好了 。接下来 , 有热key请求进来的时候 , 我们就在有备份的redis上随机选取一台 , 进行访问取值 , 返回数据 。
假设redis的集群数量为N , 步骤如下图所示
达到物理网卡上限,突然几十万的请求访问Redis的某个key如何解决

文章插图
 
注:不一定是2N , 你想取3N , 4N都可以 , 看要求 。
伪代码如下
const M = N * 2//生成随机数random = GenRandom(0, M)//构造备份新keybakHotKey = hotKey + “_” + randomdata = https://www.isolves.com/it/sjk/Redis/2019-09-03/redis.GET(bakHotKey)if data == NULL { data = GetFromDB() redis.SET(bakHotKey, expireTime + GenRandom(0,5))}业内方案
OK , 其实看完上面的内容 , 大家可能会有一个疑问 。
有办法在项目运行过程中 , 自动发现热key , 然后程序自动处理么?嗯 , 好问题 , 那我们来讲讲业内怎么做的 。其实只有两步
  1. 监控热key
  2. 通知系统做处理
监控热key
那Hermes-SDK包用来干嘛?
就是做热点发现和本地缓存 。
从监控的角度看 , 该包对于Jedis-Client的每次key值访问请求 , Hermes-SDK 都会通过其通信模块将key访问事件异步上报给Hermes服务端集群 , 以便其根据上报数据进行“热点探测” 。


推荐阅读