一文教你彻底打败Redis Bigkey和Hotkey问题

本文详细探讨了Redis中的大Key(bigkey)和热Key(hotkey)问题,包括它们的概念、危害、发现及解决方案。大Key可能导致慢查询、集群内存不均等问题,解决方法包括拆分大Key和异步删除。热Key则会造成流量集中,影响服务稳定性,可以通过多级缓存和负载均衡等策略来解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

bigkey和hotkey是Redis生产中两个比较常见的问题,本文从它们的概念、危害、发现、解决的角度,来分析一下这两个问题。

bigkey

概念

通俗易懂的讲,Big Key就是某个key对应的value很大,占用的redis空间很大,本质上是大value问题。key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。

redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。

用几个实际的例子对大Key的特征进行描述:

  • 一个String类型的Key,它的值为5MB(数据过大)
  • 一个List类型的Key,它的列表数量为20000个(列表数量过多)
  • 一个ZSet类型的Key,它的成员数量为10000个(成员数量过多)
  • 一个Hash格式的Key,它的成员数量虽然只有1000个但这些成员的value总大小为10MB(成员体积过大)

一般业界(参考阿里、快手Redis开发规范)对于key的规范如下:

string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。

危害

  • 慢查询:由于bigkey包含的数据量很大,导致一次请求的执行时间可能会很长,导致慢查询问题
  • 集群内存分布不均衡:集群模式下,bigkey较多的节点内存占用偏高,影响集群稳定性
  • 过期阻塞:当bigkey过期(删除)时,由于Redis单线程,会导致Redis阻塞从而影响客户端命令执行
  • 网卡超负荷:试想一个string类型的key数据量为10mb,这时10000个用户请求该key,那么会需要约100G的网卡带宽,影响服务器的正常运转

发现

主要思路为扫描Redis的所有Key,判断Key的长度即可。

  1. Redis 4.0以后的客户端提供了bigkeys命令,可以找出每种数据类型占用内存最多的Key。

  2. 阿里云redis大key搜索工具

删除

主要有两个办法1.遍历删除 2.Redis 异步删除命令

循环遍历删除
  1. Hash删除: hscan + hdel
public void delBigHash(String host, int port, String password, String bigHashKey) {
   
    Jedis jedis = new Jedis(host, port);
    if (password != null && !"".equals(password)) {
   
        jedis.auth(password);
    }
    ScanParams scanParams = new ScanParams().count(100);
    String cursor = "0";
    do {
   
        ScanResult<Entry<String, String>> scanResult = jedis.hscan(bigHashKey, cursor, scanParams);
        List<Entry<String, String>> entryList = scanResult.getResult();
        if (entryList != null && !entryList.isEmpty()) {
   
            for (Entry<String, String>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值