【redis】缓存设计规范

本文是 Redis 键值设计的 14 个核心规范与最佳实践,按重要程度分层说明:


一、通用数据类型选择

这里我们先给出常规的选择路径图。
redis常规选择路径
以下是对每个步骤的分析:

  1. 是否需要排序?
    • zset(有序集合)用于排序的唯一值,而list用于排序的重复值。
  2. 数据是否唯一?
    • set用于存储唯一的值。
  3. 是否需要存储对象?
    • Hash适合存储对象或具有多个字段的结构。
  4. 考虑操作频率?
    • StringHash`都是Redis中最常用的数据类型,适用于高频读写操作。
  5. 数据大小和内存占用大?
    • Bitmap适合存储大量数据,同时占用较少的内存。
  6. 消息队列?
    • stream是Redis用于实现消息队列的数据类型。
  7. 原子操作和数据过期?
    • lua脚本可以用于实现原子操作,而Redis的过期机制可以用于数据过期。

二、键设计规范(Key Design)

  1. 命名规范

    • 格式:业务模块:数据维度:唯一标识(例:user:profile:10001
    • 强制要求:禁止包含空格、换行符、不可见字符
    • 建议:长度控制在 100 字节以内(内存敏感场景)
  2. 大Key规避

    • 单Key值大小限制:
      • String 类型 ≤ 10KB
      • Hash/List/Set/Zset 元素数 ≤ 5000
    • 超标处理方案:
      • 数据分片(例:user:10001:cart_page1)
      • 启用压缩(客户端压缩 + LZF Redis压缩)
  3. 过期策略

    • 必须设置过期时间(包括持久化数据,建议 30 天兜底)
    • 不同过期时间策略:
      -- 使用随机过期时间避免批量过期导致的毛刺
      local expire_time = 86400 + math.random(0, 3600)
      redis.call('EXPIRE', KEYS[1], expire_time)
      

三、值设计规范(Value Design)

  1. 数据结构选择原则

    • 按使用频率选择:
      高频读写 → String/Hash
      范围查询 → ZSET
      去重计算 → Set/HLL
      关系查询 → RedisGraph(需 4.0+)
      
    • 禁止将 Redis 当关系型数据库使用(避免复杂关联查询)
  2. JSON序列化陷阱

    • 推荐方案:
      • 高频字段拆解为 Hash 字段
      • 保留完整 JSON 作为 fallback 方案
    • 优化案例:
      HMSET user:10001 name "John" age 30 
      SET user:10001:full '{...}' EX 3600
      
  3. 计数器设计

    • 必须使用 INCR/DECR 代替 GET+SET
    • 集群环境推荐使用 INCRBY float 代替整数运算

三、高级优化策略

  1. 内存优化技巧

    • Hash 使用 ziplist 编码:
      redis.conf 配置:
      hash-max-ziplist-entries 512
      hash-max-ziplist-value 64
      
    • 使用 SSCAN/ZSCAN 替代 SMEMBERS/ZRANGE
  2. 热点Key治理

    • 检测方法:redis-cli --hotkeys
    • 解决方案:
      • 本地缓存 + 异步刷新
      • Key 分片(例:hotkey_v1 → hotkey:{shard_id}:v1)
  3. 事务与管道

    • 管道(pipeline)批量操作控制在 100 命令/批次
    • Watch 事务中避免包含耗时操作

四、集群与持久化

  1. 集群规范

    • 单个分片内存 ≤ 10GB(AWS 内存优化型实例)
    • 跨槽操作使用 Hash Tag 需满足:
      • 相关Key必须使用相同{}内容
      • 示例:{user10001}.orders, {user10001}.profile
  2. 持久化策略

    • AOF 配置:
      appendfsync everysec
      auto-aof-rewrite-percentage 100
      auto-aof-rewrite-min-size 64mb
      
    • RDB 快照周期 ≥ 15 分钟

五、避坑指南

  1. 危险命令禁用

    rename-command FLUSHALL ""
    rename-command KEYS "internal_KEYS"
    
  2. 慢查询防御

    • 设置超时阈值:
      slowlog-log-slower-than 5000 # 5ms
      
    • 定期分析:SLOWLOG GET 50
  3. 连接池配置

    // Jedis 最佳配置示例
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(500);         // 最大连接数
    config.setMaxIdle(100);          // 最大空闲连接
    config.setMinIdle(20);           // 最小空闲连接
    config.setMaxWaitMillis(2000);   // 最大等待时间
    

六、案例

以下通过 6个高频场景的对比案例 说明 Redis 键值设计的核心规范,帮助直观理解:


案例1:用户信息存储设计

❌ 错误做法

# 大JSON直接存储String类型,无过期时间
SET user_10001 '{name:"John",age:30,address:"...20个字段...",lastLogin:...}'

问题

  • Key无业务含义,易冲突
  • Value超10KB违反大Key规范
  • 高频读取时需全量解析JSON

✅ 正确方案

# 模块化Key命名 + Hash分字段存储 + 过期时间
HMSET user:profile:10001 name "John" age 30 address "..." lastLogin 1717040000
EXPIRE user:profile:10001 2592000  # 30天过期

优化点

  • 键结构清晰:业务模块:数据维度:ID
  • 高频字段独立存取,减少网络传输
  • 兜底过期避免数据堆积

案例2:电商购物车设计

❌ 错误做法

# 用List存储所有商品ID(可能产生大Key)
LPUSH cart:10001 "sku_123:5" "sku_456:3" ...(5000+商品)

问题

  • 超出5000元素的大Key阈值
  • 分页查询困难

✅ 正确方案

# Hash分片存储 + 计数器
HMSET cart:10001:page1 sku_123 5 sku_456 3
HMSET cart:10001:page2 sku_789 2 ...
# 获取商品数量(原子操作)
HINCRBY cart:10001:page1 sku_123 1 

优化点

  • 分片控制单个Key元素数量
  • 利用Hash字段的原子计数特性

案例3:秒杀库存热点Key

❌ 错误做法

# 集中式库存计数器(产生热点Key)
SET stock:sku_8888 1000
DECR stock:sku_8888  # 所有请求集中访问此Key

问题

  • 单Key承受极高QPS
  • 集群模式下无法分散压力

✅ 正确方案

# 库存分片设计
SET stock:sku_8888:shard1 200
SET stock:sku_8888:shard2 200
...
SET stock:sku_8888:shard5 200# 客户端随机选择分片扣减
DECR stock:sku_8888:shard{random(1-5)}

优化点

  • 通过分片分散热点
  • 结合本地缓存减少Redis访问

案例4:页面访问计数器

❌ 错误做法

# 非原子操作导致计数不准
count = redis.GET('page_view:home')
redis.SET('page_view:home', count+1)

问题

  • 并发场景下数据不一致
  • 频繁GET/SET产生大量请求

✅ 正确方案

# 使用INCR原子操作
INCR page_view:home# 按小时滚动存储(避免单Key过大)
INCR page_view:home:2024052715

优化点

  • 原子操作保证准确性
  • 时间分片控制Key规模

案例5:用户消息通知列表

❌ 错误做法

# 用String存储JSON数组(频繁全量读写)
SET msg:10001 '[{id:1,content:"..."}, {...1000条数据}]'

问题

  • 大Value导致网络阻塞
  • 修改任意消息需全量更新

✅ 正确方案

# 使用ZSET按时间排序存储
ZADD msg:10001 1717040000 '{"id":1,"content":"..."}'
ZADD msg:10001 1717040001 '{"id":2,"content":"..."}'# 分页查询最新消息
ZREVRANGE msg:10001 0 9 WITHSCORES

优化点

  • 天然支持按时间排序和分页
  • 单个消息的增删不影响整体

案例6:社交关系存储

❌ 错误做法

# 用String存储用户粉丝列表(大JSON数组)
SET followers:10001 "[20001,20002,...50000个用户ID]"

问题

  • 50000个ID超过大Key限制
  • 判断是否关注需全量扫描

✅ 正确方案

# 使用Set存储关系 + 分页控制
SADD following:10001 20001 20002 ...  # 最多5000元素/Key
SADD following:10001:page2 20003 ...  # 分片存储# 检查关注关系
SISMEMBER following:10001 20001

优化点

  • 分片规避大Key
  • 使用原生集合操作提升效率

总结技巧

  1. Key设计三要素:业务线明确(user)、数据类型清晰(profile)、标识唯一(10001
  2. Value选择原则
    • 优先使用 Hash 替代 String 存储对象
    • 需要排序用 ZSET去重用 Set队列用 List
  3. 性能压测公式
    # 模拟高并发场景
    redis-benchmark -h 127.0.0.1 -p 6379 -n 100000 -c 100 -t set,get
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/894937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021 年 9 月青少年软编等考 C 语言五级真题解析

目录 T1. 问题求解思路分析T2. 抓牛思路分析T3. 交易市场思路分析T4. 泳池思路分析T1. 问题求解 给定一个正整数 N N N,求最小的 M M M 满足比 N N N 大且 M M M 与 N N N 的二进制表示中有相同数目的 1 1 1。 举个例子,假如给定 N N N 为 78 78 78,二进制表示为 …

Windows 中学习Docker环境准备2、Docker Desktop中安装ubuntu

Windows 中学习Docker环境准备1、Win11安装Docker Desktop Windows 中学习Docker环境准备2、Docker Desktop中安装ubuntu Windows 中学习Docker环境准备3、在Ubuntu中安装Docker 需要更多Docker学习视频和资料,请文末联系 一、安装 Docker Desktop 下载 Docker…

LabVIEW2025中文版软件安装包、工具包、安装教程下载

下载链接:LabVIEW及工具包大全-三易电子工作室http://blog.eeecontrol.com/labview6666 《LabVIEW2025安装图文教程》 1、解压后,双击install.exe安装 2、选中“我接受上述2条许可协议”,点击下一步 3、点击下一步,安装NI Packa…

PHP ODBC:深入探索数据库连接与交互技术

PHP ODBC:深入探索数据库连接与交互技术 引言 PHP作为一种广泛使用的服务器端脚本语言,在Web开发中扮演着重要角色。在数据处理方面,PHP与数据库的交互是其核心功能之一。ODBC(Open Database Connectivity)作为一种标准数据库访问接口,允许PHP应用程序与各种数据库系统…

AUTOSAR汽车电子嵌入式编程精讲300篇-基于FPGA的CAN FD汽车总线数据交互系统设计

目录 前言 汽车总线以及发展趋势 汽车总线技术 汽车总线发展趋势 CAN FD总线国内外研究现状 2 系统方案及CAN FD协议分析 2.1系统控制方案设计 2.2 CAN FD总线帧结构分析 2.2.1数据帧分析 2.2.2远程帧分析 2.2.3过载帧分析 2.2.4错误帧分析 2.2.5帧间隔分析 2.3位…

BUU17 [RoarCTF 2019]Easy Calc1

自用 源代码 $(#calc).submit(function(){$.ajax({url:"calc.php?num"encodeURIComponent($("#content").val()),type:GET,success:function(data){$("#result").html(<div class"alert alert-success"><strong>答案:&l…

5. k8s二进制集群之ETCD集群部署

下载etcd安装包创建etcd配置文件准备证书文件和etcd存储目录ETCD证书文件安装(分别对应指定节点)创建证书服务的配置文件启动etcd集群验证etcd集群状态继续上一篇文章《k8s二进制集群之ETCD集群证书生成》下面介绍一下etcd证书生成配置。 下载etcd安装包 https://github.com…

Java并发编程笔记

Java并发基础知识补全 启动 启动线程的方式只有&#xff1a; 1、X extends Thread;&#xff0c;然后X.start 2、X implements Runnable&#xff1b;然后交给Thread运行 线程的状态 Java中线程的状态分为6种&#xff1a; 1. 初始(NEW)&#xff1a;新创建了一个线程对象&…

使用多模态大语言模型进行深度学习的图像、文本和语音数据增强

在过去的五年里&#xff0c;研究方向已从传统的机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09;方法转向利用大语言模型&#xff08;LLMs&#xff09;&#xff0c;包括多模态方法&#xff0c;用于数据增强&#xff0c;以提高泛化能力&#xff0c;并在…

Windows Docker笔记-Docker拉取镜像

通过在前面的章节《安装docker》中&#xff0c;了解并安装成功了Docker&#xff0c;本章讲述如何使用Docker拉取镜像。 使用Docker&#xff0c;主要是想要创建并运行Docker容器&#xff0c;而容器又要根据Docker镜像来创建&#xff0c;那么首当其冲&#xff0c;必须要先有一个…

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-autobatch.py

autobatch.py ultralytics\utils\autobatch.py 目录 autobatch.py 1.所需的库和模块 2.def check_train_batch_size(model, imgsz640, ampTrue, batch-1, max_num_obj1): 3.def autobatch(model, imgsz640, fraction0.60, batch_sizeDEFAULT_CFG.batch, max_num_obj1): …

【文件上传、秒传、分片上传、断点续传、重传】

文章目录 获取文件对象文件上传&#xff08;秒传、分片上传、断点续传、重传&#xff09;优化 获取文件对象 input标签的onchange方法接收到的参数就是用户上传的所有文件 <html lang"en"><head><title>文件上传</title><style>#inp…

Office/WPS接入DS等多个AI工具,开启办公新模式!

在现代职场中&#xff0c;Office办公套件已成为工作和学习的必备工具&#xff0c;其功能强大但复杂&#xff0c;熟练掌握需要系统的学习。为了简化操作&#xff0c;使每个人都能轻松使用各种功能&#xff0c;市场上涌现出各类办公插件。这些插件不仅提升了用户体验&#xff0c;…

FPGA的IP核接口引脚含义-快解

疑问 手册繁琐&#xff0c;怎样快速了解IP核各输入输出接口引脚的含义。 答疑 不慌不慌&#xff0c;手册确实比较详细但繁琐&#xff0c;如何快速知晓该部分信息&#xff0c;涛tao道长给你们说&#xff0c;简单得很&#xff0c;一般新入门的道友有所不知&#xff0c;往往后面…

GnuTLS: 在 pull 函数中出错。 无法建立 SSL 连接。

提示信息 [root@localhost ~]# wget https://download.docker.com/linux/static/stable/x86_64/docker-27.5.1.tgz --2025-02-06 12:45:34-- https://download.docker.com/linux/static/stable/x86_64/docker-27.5.1.tgz 正在解析主机 download.docker.com (download.docker.…

Python3+Request+Pytest+Allure+Jenkins 接口自动化测试[手动写的和AI写的对比]

我手动写的参考 总篇:Python3+Request+Pytest+Allure+Jenkins接口自动化框架设计思路_jenkins python3+request-CSDN博客 https://blog.csdn.net/fen_fen/article/details/144269072 下面是AI写的:Python3+Request+Pytest+Allure+Jenkins 接口自动化测试[AI文章框架] 在软…

告别手动操作!用Ansible user模块高效管理 Linux账户

在企业运维环境中&#xff0c;服务器的用户管理是一项基础但非常重要的任务。比如&#xff0c;当有新员工加入时&#xff0c;我们需要在多台服务器上为他们创建账户并分配合适的权限。而当员工离职或岗位发生变化时&#xff0c;我们也需要迅速禁用或删除他们的账户&#xff0c;…

ADC模数转换器概念函数及应用

ADC模数转换器概念函数及应用 文章目录 ADC模数转换器概念函数及应用1.ADC简介2.逐次逼近型ADC2.1逐次逼近型ADC2.2stm32逐次逼近型2.3ADC基本结构2.4十六个通道 3.规则组的4种转换模式3.1单次转换&#xff0c;非扫描模式3.2连续转换&#xff0c;非扫描模式3.3单次转换&#xf…

探索前端框架的未来:Svelte 的崛起

引言 在前端开发的世界里&#xff0c;框架更新换代的速度仿佛光速。从 jQuery 到 Angular&#xff0c;再到如今大热的 React 和 Vue&#xff0c;开发者们不断追逐更轻量、更快、更易于维护的框架。如今&#xff0c;Svelte 正悄然崛起&#xff0c;并引发了关于前端框架未来的热烈…

DeepSeek在FPGA/IC开发中的创新应用与未来潜力

随着人工智能技术的飞速发展&#xff0c;以DeepSeek为代表的大语言模型&#xff08;LLM&#xff09;正在逐步渗透到传统硬件开发领域。在FPGA&#xff08;现场可编程门阵列&#xff09;和IC&#xff08;集成电路&#xff09;开发这一技术密集型行业中&#xff0c;DeepSeek凭借其…