讲了几天的数据库系列的文章, 大家一定看烦了, 其实还没讲完...(以下省略一万字).
今天我们换换口味, 来写 Redis 方面的内容, 谈谈热 key 问题如何解决.
其实热 key 问题说来也很简单, 就是瞬间有几十万的请求去访问 Redis 上某个固定的 key, 从而压垮缓存服务的情情况.
其实生活中也是有不少这样的例子. 比如 XX 明星结婚. 那么关于 XX 明星的 Key 就会瞬间增大, 就会出现热数据问题.
ps: hot key 和 big key 问题, 大家一定要有所了解.
本文预计分为如下几个部分
热 key 问题
如何发现
业内方案
正文
热 Key 问题
上面提到, 所谓热 key 问题就是, 突然有几十万的请求去访问 Redis 上的某个特定 key. 那么, 这样会造成流量过于集中, 达到物理网卡上限, 从而导致这台 Redis 的服务器宕机.
那接下来这个 key 的请求, 就会直接怼到你的数据库上, 导致你的服务不可用.
怎么发现热 key
方法一: 凭借业务经验, 进行预估哪些是热 key
其实这个方法还是挺有可行性的. 比如某商品在做秒杀, 那这个商品的 key 就可以判断出是热 key. 缺点很明显, 并非所有业务都能预估出哪些 key 是热 key.
方法二: 在客户端进行收集
这个方式就是在操作 Redis 之前, 加入一行代码进行数据统计. 那么这个数据统计的方式有很多种, 也可以是给外部的通讯系统发送一个通知信息. 缺点就是对客户端代码造成入侵.
方法三: 在 Proxy 层做收集
有些集群架构是下面这样的, Proxy 可以是 Twemproxy, 是统一的入口. 可以在 Proxy 层做收集上报, 但是缺点很明显, 并非所有的 Redis 集群架构都有 proxy.
方法四: 用 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, 步骤如下图所示
来源: http://www.tuicool.com/articles/BN7Br2I