Redis-键值设计

04-19 阅读 0评论

Redis-键值设计

1.设置key的规范

  1. 遵循基本格式:【业务名称】:【数据名】:【id】 可读性强,在客户端的情况下使用:如果前缀相同会分目录层级
  2. 长度不超过44字节 string数据结构的三种类型,在44字节之内是embstring 内存占用小
  3. 不包含特殊字符

优点

  • 可读性强
  • 避免key冲突
  • 方便估计案例
  • 更节省内存

    2.BigKey

    什么是BigKey

    在redis中存储的value空间大,导致效率变低。

    BigKey的危害
    1. 网络阻塞

      对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,网络速度变慢

    2. 数据倾斜

      BigKey所在的Redis示例内存使用率远超其他示例

    3. Redis阻塞

      对元素较多的hash,list,zset,set做运算会耗时

    4. CPU压力

      对BigKey的数据序列化和反序列化会导致cpu的使用飙升

    如何排查BigKey
    1. redis-cli-bigkeys

    2. scan扫描 Java代码示例

      引入pom

                  redis.clients
                  jedis
                  3.8.0 
              
      
      /**
       * 排查大key
       *
       */
      @SpringBootTest
      public class RedisScanBigKey {
          /**
           * 字符串的大key
           */
          final static int STR_MAX_LEN = 10 * 1024;
          /**
           * 集合的大key
           */
          final static int HASH_MAX_LEN = 500;
          @Test
          public void scanBigKey() {
              Jedis jedis = new Jedis("localhost", 6379);
              int maxLen = 0;
              long len = 0;
              // 开始游标,首次调用传入0
              String cursor = "0";
              do {
                  // 执行SCAN命令,传入游标、匹配模式(可选)和COUNT(可选)
                  ScanResult scanResult = jedis.scan(cursor);
                  cursor = scanResult.getCursor();
                  // 处理本次扫描返回的元素
                  List list = scanResult.getResult();
                  if (CollectionUtil.isEmpty(list)) {
                      break;
                  }
                  // 遍历
                  for (String key : list) {
                      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("大Key的值 : %s, type: %s, length or size: %d %n", key, type, len);
                      }
                      // 检查是否已遍历完所有元素
                  }
              }
                  while (!"0".equals(cursor));
          }
      }
      
    3. 第三方工具

    4. 网络监控

    如何删除大BigKey

    bigkey内存占用较多,即使删除也需要占用非常多的时间,导致redis主线程阻塞

    • redis3.0以下版本:如果是集合类型则遍历bigkey的元素,逐个删除.建议使用scan扫描然后以此删除
    • redis4.0以后:提供了异步删除命令:unlink

      3.使用恰当的数据类型

      Redis-键值设计

      Redis-键值设计

      /**
           * 给大key瘦身 拆分成小hash
           */
          @Test
          void smallHash(){
              Jedis jedis = new Jedis("localhost", 6379);
              int hashSize = 100;
              Map map = new HashMap(hashSize);
              for (int i = 0; i 
                      
                      
                      

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]