当前位置: 首页 > news >正文

Redis在实践的关键点

Redis键值设计

优雅的key结构

Redis的Key虽然可以自定义,但最好遵循下面的几个最佳实践约定:

  • 遵循基本格式:[业务名称]:[数据名]:[id]
  • 长度不超过44字节
  • 不包含特殊字符

例如:我们的登录业务,保存用户信息,其key可以设计成如下格式:

这样设计的好处:

  • 可读性强
  • 避免key冲突
  • 方便管理
  • 更节省内存: key是string类型,底层编码包含int、embstr和raw三种。embstr在小于44字节使用,采用连续内存空间,内存占用更小。当字节数大于44字节时,会转为raw模式存储,在raw模式下,内存空间不是连续的,而是采用一个指针指向了另外一段内存空间,在这段空间里存储SDS内容,这样空间不连续,访问的时候性能也就会收到影响,还有可能产生内存碎片

docker进入redis客户端指令

docker exec -it <redis_container_name_or_id> /bin/bash

再输入

redis_cli

拒绝BigKey

什么是BigKey

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

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

那么如何判断元素的大小呢?redis也给我们提供了命令

推荐值:

  • 单个key的value小于10KB
  • 对于集合类型的key,建议元素数量小于1000

BigKey的危害
  • 网络阻塞
    • 对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢
  • 数据倾斜
    • BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡
  • Redis阻塞
    • 对元素较多的hash、list、zset等做运算会耗时较旧,使主线程被阻塞
  • CPU压力
    • 对BigKey的数据序列化和反序列化会导致CPU的使用率飙升,影响Redis实例和本机其它应用

如何发现BigKey
  1. redis-cli --bigkeys

利用redis-cli提供的--bigkeys参数,可以遍历分析所有key,并返回Key的整体统计信息与每个数据的Top1的big key

命令:redis-cli -a <redis_password> --bigkeys

  1. scan扫描

自己编程,利用scan扫描Redis中的所有key,利用strlen、hlen等命令判断key的长度(此处不建议使用MEMORY USAGE)

package com.itcam.test;import com.itcam.jedis.util.JedisConnectionFactory;
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.HashMap;
import java.util.List;
import java.util.Map;public class JedisTest {private Jedis jedis;@BeforeEachvoid setUp() {// 1.建立连接jedis = JedisConnectionFactory.getJedis();// 2.设置密码jedis.auth("123321");// 3.选择库jedis.select(0);}final static int STR_MAX_LEN = 10 * 1024;final static int HASH_MAX_LEN = 500;@Testvoid testScan() {int maxLen = 0;long len = 0;String cursor = "0";do {// 扫描并获取一部分keyScanResult<String> result = jedis.scan(cursor);// 记录cursorcursor = 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.equals("0"));}@AfterEa

http://www.mrgr.cn/news/55771.html

相关文章:

  • 第十八课:Python学习之多态
  • expressjs 如何记录操作日志
  • 解决Git合并冲突:掌握版本控制的精髓
  • H3C路由器交换机操作系统介绍
  • 利用 PyTorch 进行深度学习训练过程中模型的 .eval() 和 .train() 属性介绍
  • Java 中的【初始化块】
  • autMan框架对接飞书机器人
  • Golang | Leetcode Golang题解之第500题键盘行
  • Flutter Container容器组件实战案例
  • 精选录屏软件下载工具:记录精彩每一刻
  • 基于leaflet-polygon.fillPattern的面状对象图片填充实现
  • SQL CHECK 约束:确保数据完整性的关键
  • 【星闪技术】WS63E模块实时显示当前环境温湿度
  • ARL 灯塔 | CentOS7 — ARL 灯塔搭建流程(Docker)
  • AI学习指南深度学习篇-对比学习(Contrastive Learning)简介
  • 用malloc申请空间的开辟和free空间的释放
  • 计算机网络基本命令
  • 《深度学习》 了解YOLO基本知识
  • Java全栈经典面试题剖析2】JavaSE面向对象1
  • 复盘秋招22场面试(四)形势重新评估与后续措施
  • 【论文学习与撰写】,论文word文档中出现乱码的情况,文档中显示的乱码,都是英文字母之类的,但打印预览是正常的
  • ARL 灯塔 | ARL 灯塔 — 指纹添加
  • Java最全面试题->Java主流框架->Srping面试题
  • JavaSE——IO流4:高级流(转换流InputStreamReader、OutputStreamWriter)
  • 点云处理中的三种近邻搜索方法:K近邻、体素内近邻和半径内近邻搜索
  • OpenSEMBA :一个用于电磁场模拟的开源软件框架