Redis 扫描 bigKey

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis 扫描 bigKey

BigKey通常以Key的大小和Key中成员的数量来综合判定,例如:


  • Key本身的数据量过大:一个String类型的Key,它的值为5 MB


  • Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个


  • Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的Value(值)总大小为100 MB


BigKey的危害


  • 网络阻塞


  • 对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢


  • 数据倾斜


  • BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡


  • Redis阻塞


  • 对元素较多的hash、list、zset等做运算会耗时较旧,使主线程被阻塞


  • CPU压力


  • 对BigKey的数据序列化和反序列化会导致CPU的使用率飙升,影响Redis实例和本机其它应用


工具类扫描出 bigKey


package com.icsomserver.business.test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanResult;
import java.util.List;
public class JedisTest {
    private Jedis jedis;
    @BeforeEach
    void setUp() {
        // 1.建立连接
        jedis = new Jedis("127.0.0.1", 6379);
        // 2.设置密码
        //jedis.auth("123321");
        // 3.选择库
        jedis.select(0);
    }
    final static int STR_MAX_LEN = 10 * 1024;
    final static int HASH_MAX_LEN = 500;
    @Test
    void testScan() {
        int maxLen = 0;
        long len = 0;
        int cursor = 0;
        do {
            // 扫描并获取一部分key
            ScanResult<String> result = jedis.scan(cursor);
            // 记录cursor
            cursor = result.getCursor();
            List<String> list = result.getResult();
            if (list == null || list.isEmpty()) {
                break;
            }
            // 遍历
            for (String key : list) {
                // 判断key的类型
                String type = jedis.type(key);
                switch (type) {
                    case "string":
                        len = jedis.strlen(key);
                        maxLen = STR_MAX_LEN;
                        break;
                    case "hash":
                        len = jedis.hlen(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    case "list":
                        len = jedis.llen(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    case "set":
                        len = jedis.scard(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    case "zset":
                        len = jedis.zcard(key);
                        maxLen = HASH_MAX_LEN;
                        break;
                    default:
                        break;
                }
                if (len >= maxLen) {
                    System.out.printf("Found big key : %s, type: %s, length or size: %d %n", key, type, len);
                }
            }
        } while (cursor != 0);
    }
    @AfterEach
    void tearDown() {
        if (jedis != null) {
            jedis.close();
        }
    }
}


需要引入的 pom


<!--单元测试-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.1</version>
</dependency>


如何删除 BigKey


BigKey内存占用较多,即便时删除这样的key也需要耗费很长时间,导致Redis主线程阻塞,引发一系列问题。


  • redis 3.0 及以下版本


  • 如果是集合类型,则遍历BigKey的元素,先逐个删除子元素,最后删除BigKey


  • Redis 4.0以后


  • Redis在4.0后提供了异步删除的命令:unlink
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
存储 监控 NoSQL
一篇搞定Redis中的BigKey问题
BigKey的具体表现是redis中的key对应的value很大,占用的redis空间比较大,本质上是大value问题。
1074 0
|
15天前
|
NoSQL Redis
Redis入门到通关之扫描 bigKey
Redis入门到通关之扫描 bigKey
21 0
|
9月前
|
存储 NoSQL 算法
Redis中的BigKey问题:排查与解决思路
Redis中的BigKey问题:排查与解决思路
405 0
|
7月前
|
存储 NoSQL Redis
Redis之bigkey问题解读
Redis之bigkey问题解读
|
10月前
|
存储 NoSQL Redis
Redis del bigkey即使开启了lazyfree,为什么还是阻塞的,但是别人又不阻塞?why
Redis del bigkey即使开启了lazyfree,为什么还是阻塞的,但是别人又不阻塞?why
|
存储 缓存 JSON
Redis的bigkey了解过吗---让面试官无话可问【面试题】
写作目的 好久没更新博客了,最近受到一个说“理论-实操-小总结”大佬的点拨,问我bigkey了解过吗?他说你不用告诉我你的答案,你就说你“实操”过吗???我。。。
165 0
Redis的bigkey了解过吗---让面试官无话可问【面试题】
|
存储 NoSQL 算法
【Redis核心原理专题】(1)「技术提升系列」分析探究如何实现LFU的热点key发现机制以及内部的Scan扫描技术的原理
【Redis核心原理专题】(1)「技术提升系列」分析探究如何实现LFU的热点key发现机制以及内部的Scan扫描技术的原理
156 0
【Redis核心原理专题】(1)「技术提升系列」分析探究如何实现LFU的热点key发现机制以及内部的Scan扫描技术的原理
|
存储 缓存 JSON
Redis BigKey介绍
Redis BigKey介绍
215 0
|
存储 缓存 运维
深度干货|一文详解 Redis 中 BigKey、HotKey 的发现与处理
在Redis的使用过程中,我们经常会遇到BigKey(下文将其称为“大key”)及HotKey(下文将其称为“热key”)。大Key与热Key如果未能及时发现并进行处理,很可能会使服务性能下降、用户体验变差,甚至引发大面积故障。本文详解 Redis 中 BigKey、HotKey 的发现与处理。
2508 0
深度干货|一文详解 Redis 中 BigKey、HotKey 的发现与处理
|
1月前
|
存储 NoSQL 算法
09- Redis分片集群中数据是怎么存储和读取的 ?
Redis分片集群使用哈希槽分区算法,包含16384个槽(0-16383)。数据存储时,通过CRC16算法对key计算并模16383,确定槽位,进而分配至对应节点。读取时,根据槽位找到相应节点直接操作。
66 12