一、热key问题

热key问题: 在redis数据库中有些访问量特别大的数据,比如热门商品信息、热门话题等,大量的请求去访问redis上的某个特定key,会造成流量过于集中,达到物理网卡或者内存上限,从而导致服务器宕机。

如何发现:

  1. 提前预估:根据业务特点可以提前预估一部分热点数据。如,促销活动商品,热门话题,节假日话题,纪念日活动等。

  2. 在客户端进行收集:调用端通过代码计数的方式统计 key 的请求次数,代码侵入性强。

  3. 在Proxy层做收集:Twemproxy,codis 这些基于代理的 Redis 分布式架构,统一的入口,可以在 Proxy 层做收集上报,但是并非所有的 Redis 集群架构都有 proxy。

  4. Redis 服务端收集:Redis 提供了 monitor 命令(也有现成的分析工具,比如redis-faina),可以统计出一段时间内的某 Redis 节点上的所有命令,分析热点 key,在高并发条件下,会存在内存暴涨和 Redis 性能的隐患,所以此种方法适合在短时间内使用;同样只能统计一个 Redis 节点的热点 key,对于集群需要汇总统计,业务角度讲稍微麻烦一点。
    Redis 4.0.3同时也提供了redis-cli的热点key发现功能,执行redis-cli时加上–hotkeys选项即可

如何解决:

  1. 本地缓存

  2. 利用分片算法的特性,对key进行打散处理:给热key加上前缀或者后缀,把一个热key的数量变成 redis 实例个数N的倍数M,从而由访问一个热key成访问 N * M 个redis key。 经过分片分布到不同的实例上,将访问量均摊到所有实例。

二、大key问题

大key问题: 有些 key 访问 QPS 虽然不高,但是由于 value 很大,造成网卡负载较大,网卡流量被打满,单台机器可能出现千兆 / 秒,IO 故障。大key操作通常可见于集群慢日志,同期会伴随缓存调用的高延迟,甚至节点完全阻塞造成的不可用。

多大的value算大: 和服务器的性能有一定的关系,一般来说string 类型 value > 10K,set、list、hash、zset 等集合数据类型中的元素个数 > 1000。

如何解决:

  1. 数据结构拆分,将操作压力平摊到多个 redis 实例中,降低对单个 redis 的 IO 影响

  2. 数据分片,比如后面加序号,进行多实例的拆分

优雅的删除大key

  1. 主动删除 UNLINK xxxkey

    unlink 命令是 del 的异步版本,由 Lazyfree 机制实现。Lazyfree 机制的原理是在删除的时候只进行逻辑删除,把 key 释放操作放在 bio (Background I/O)单独的子线程中惰性处理,减少删除大 key 对 redis 主线程的阻塞,有效地避免因删除大key带来的性能问题。unlink 即使在批量删除 大 key 时,也不会对阻塞造成阻塞。

  2. 被动删除

    被动删除是指 Redis 自身的 key 清除策略,一个 大 key 过期或者被淘汰时,如何被清除,会不会导致阻塞?4.0 以前自动清除是有可能阻塞主线程的。
    4.0 以后的版本,被动删除策略是可选的配置参数,允许以 Lazyfree 的方式清除。但是参数默认是关闭的,可配置如下参数开启。

    lazyfree-lazy-expire on # 过期惰性删除

    lazyfree-lazy-eviction on # 超过最大内存惰性删除

    lazyfree-lazy-server-del on # 服务端被动惰性删除

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐