问题

如热点新闻、商品的巨大流量,对存储这类信息的 Redis 是一个巨大的负载。

以 Redis Cluster 为例,热点数据会造成整体流量的不均衡、个别节点出现 OPS 过大的情况,甚至超过 Redis 节点本身可承受的最大 OPS。

如何分析热点 Key

客户端

当客户端发起 Redis 命令的时候,可在每次调用的时候,进行统计记录。

易实现,但也存在问题:

  • 无法预知 Key 的个数,存在内存泄漏的风险
  • 对客户端代码有侵入,多客户端或多语言,都需维护该逻辑,增加维护成本
  • 只能了解当前客户端所使用的 Redis 信息,无法实现运维规模化;

代理端

如:Twemproxy、Codis 等代理的 Redis 分布式架构。该架构最适合做 Redis 热点 key 统计。

Redis 服务器

使用 Redis 自带的 monitor 命令统计热点。

Facebook 开源的 redis-faina 利用该原理使用 Python 实现。

问题:

  • monitor 命令在高并发条件下,存在内存暴增和影响 Redis 性能的隐患,只适合在短时间内使用。
  • 只能统计一个 Redis 节点的热点 key;对于 Redis 集群需要汇总统计。

机器

Redis 客户端使用 TCP 协议与服务端交互、通行协议采用 RESP。

即:可通过对机器的 Redis 端口进行 TCP 抓包完成 Redis 热点 Key 的统计。

该方法对客户端与服务器毫无侵入,相对完美;但也存在两个问题:

  • 需要一定的开发成本,相关的实现方案:ELK体系下的 packetbeat 插件,可实现对 Redis、MySQL 等众多主流服务的数据抓包、分析、报表展示。
  • 以机器进行统计,想了解整个集群,还需好后期进行汇总。

对比

方案 优点 缺点
客户端
- 实现简单

- 内存蟹肉风险
- 维护成本高
- 只能统计单个客户端
代理
- 代理是客户端与服务端的桥梁,实现最方便、最系统

- 增加代理端的开发部署成本
- 存在一定的网络消耗、性能损耗
服务端
- 实现简单

- monitor 本身的使用成本与危害
- 只能短时间使用
- 只能统计单个 Redis 节点
机器
- 对于客户端、服务端无侵入和影响

- 需专业运维团队开发、增加机器部署成本

总结

总结解决 Redis 热点 key 的三个方案:

  • 拆分复杂数据结构:如将 key 拆分为多个 key,减少 Redis 单节点或单数据类型的性能瓶颈。
  • 迁移热点 key:如 Redis Cluster 可将热点 key 所在的 slot 迁移到其他高性能的节点上
  • 本地缓存加通知机制:将热点 key 存放到 客户端本地缓存内