【redis】缓存设计规范
本文是 Redis 键值设计的 14 个核心规范与最佳实践,按重要程度分层说明:
一、通用数据类型选择
这里我们先给出常规的选择路径图。

以下是对每个步骤的分析:
- 是否需要排序?:
zset(有序集合)用于排序的唯一值,而list用于排序的重复值。
- 数据是否唯一?:
set用于存储唯一的值。
- 是否需要存储对象?:
Hash适合存储对象或具有多个字段的结构。
- 考虑操作频率?:
- String
和Hash`都是Redis中最常用的数据类型,适用于高频读写操作。
- String
- 数据大小和内存占用大?:
Bitmap适合存储大量数据,同时占用较少的内存。
- 消息队列?:
stream是Redis用于实现消息队列的数据类型。
- 原子操作和数据过期?:
lua脚本可以用于实现原子操作,而Redis的过期机制可以用于数据过期。
二、键设计规范(Key Design)
-
命名规范
- 格式:
业务模块:数据维度:唯一标识(例:user:profile:10001) - 强制要求:禁止包含空格、换行符、不可见字符
- 建议:长度控制在 100 字节以内(内存敏感场景)
- 格式:
-
大Key规避
- 单Key值大小限制:
- String 类型 ≤ 10KB
- Hash/List/Set/Zset 元素数 ≤ 5000
- 超标处理方案:
- 数据分片(例:user:10001:cart_page1)
- 启用压缩(客户端压缩 + LZF Redis压缩)
- 单Key值大小限制:
-
过期策略
- 必须设置过期时间(包括持久化数据,建议 30 天兜底)
- 不同过期时间策略:
-- 使用随机过期时间避免批量过期导致的毛刺 local expire_time = 86400 + math.random(0, 3600) redis.call('EXPIRE', KEYS[1], expire_time)
三、值设计规范(Value Design)
-
数据结构选择原则
- 按使用频率选择:
高频读写 → String/Hash 范围查询 → ZSET 去重计算 → Set/HLL 关系查询 → RedisGraph(需 4.0+) - 禁止将 Redis 当关系型数据库使用(避免复杂关联查询)
- 按使用频率选择:
-
JSON序列化陷阱
- 推荐方案:
- 高频字段拆解为 Hash 字段
- 保留完整 JSON 作为 fallback 方案
- 优化案例:
HMSET user:10001 name "John" age 30 SET user:10001:full '{...}' EX 3600
- 推荐方案:
-
计数器设计
- 必须使用
INCR/DECR代替GET+SET - 集群环境推荐使用
INCRBY float代替整数运算
- 必须使用
三、高级优化策略
-
内存优化技巧
- Hash 使用 ziplist 编码:
redis.conf 配置: hash-max-ziplist-entries 512 hash-max-ziplist-value 64 - 使用
SSCAN/ZSCAN替代SMEMBERS/ZRANGE
- Hash 使用 ziplist 编码:
-
热点Key治理
- 检测方法:
redis-cli --hotkeys - 解决方案:
- 本地缓存 + 异步刷新
- Key 分片(例:hotkey_v1 → hotkey:{shard_id}:v1)
- 检测方法:
-
事务与管道
- 管道(pipeline)批量操作控制在 100 命令/批次
- Watch 事务中避免包含耗时操作
四、集群与持久化
-
集群规范
- 单个分片内存 ≤ 10GB(AWS 内存优化型实例)
- 跨槽操作使用 Hash Tag 需满足:
- 相关Key必须使用相同{}内容
- 示例:
{user10001}.orders,{user10001}.profile
-
持久化策略
- AOF 配置:
appendfsync everysec auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb - RDB 快照周期 ≥ 15 分钟
- AOF 配置:
五、避坑指南
-
危险命令禁用
rename-command FLUSHALL "" rename-command KEYS "internal_KEYS" -
慢查询防御
- 设置超时阈值:
slowlog-log-slower-than 5000 # 5ms - 定期分析:
SLOWLOG GET 50
- 设置超时阈值:
-
连接池配置
// 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
- 使用原生集合操作提升效率
总结技巧
- Key设计三要素:业务线明确(
user)、数据类型清晰(profile)、标识唯一(10001) - Value选择原则:
- 优先使用 Hash 替代 String 存储对象
- 需要
排序用 ZSET,去重用 Set,队列用 List
- 性能压测公式:
# 模拟高并发场景 redis-benchmark -h 127.0.0.1 -p 6379 -n 100000 -c 100 -t set,get
相关文章:
【redis】缓存设计规范
本文是 Redis 键值设计的 14 个核心规范与最佳实践,按重要程度分层说明: 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析: 是否需要排序?: zset(有序集合)用…...
【愚公系列】《循序渐进Vue.js 3.x前端开发实践》061-Vue Router的动态路由
标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主&…...
流媒体缓存管理策略
缓存管理策略是指为了优化性能、资源使用和用户体验而对缓存数据进行管理的方法和规则。以下是一些常见的缓存管理策略: 1. LRU(Least Recently Used,最近最少使用) 原理:当缓存满了,需要腾出空间时&…...
2025简约的打赏系统PHP网站源码
源码介绍 2025简约的打赏系统PHP网站源码 源码上传服务器,访问域名/install.php安装 支持自定义金额打赏 集成支付宝当面付 后台管理系统 订单记录查询 效果预览 源码获取 2025简约的打赏系统PHP网站源码...
交叉编译工具链下载和使用
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
BUU28 [GXYCTF2019]BabySQli1
常规万能密码,发现登不上去 过滤掉了or,,当尝试了n种方法以后,最关键的是发现()居然也被过滤了 哈哈,那玩个淡, 再搜wp!! 当输入admin的时候,提示密码错误࿰…...
ubuntu20.04+RTX4060Ti大模型环境安装
装显卡驱动 这里是重点,因为我是跑深度学习的,要用CUDA,所以必须得装官方的驱动,Ubuntu的附件驱动可能不太行. 进入官网https://www.nvidia.cn/geforce/drivers/,选择类型,最新版本下载。 挨个运行&#…...
Rust语言进阶之标准输入: stdin用法实例(一百零五)
简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【…...
结构化表达(三):归纳分组
目录 归纳分组 一、如何归纳分组 二、如何掌握更多模型 归纳分组 一、如何归纳分组 整理思路,多用分类模型,列如: 1、内部、外部分类。 2、市场营销学中的4P:产品、渠道、价格、促销。 3、战略3C:公司、客户、竞…...
5G技术解析:从核心概念到关键技术
1. 引言 5G技术的迅猛发展正在重塑我们的生活方式和社会结构。它不仅仅是新一代的移动通信技术,更是一场深刻的技术革命。5G网络正在以其惊人的高速、低延迟和大带宽能力,为智能家居、自动驾驶、工业自动化、远程医疗等另一带来前所未有的可能性。 本文…...
DeepSeek 引领的 AI 范式转变与存储架构的演进
近一段时间,生成式 AI 技术经历了飞速的进步,尤其是在强推理模型(Reasoning-LLM)的推动下,AI 从大模型训练到推理应用的范式发生了剧变。以 DeepSeek 等前沿 AI 模型为例,如今的 AI 技术发展已不局限于依赖…...
基于Hexo实现一个静态的博客网站
原文首发:https://blog.liuzijian.com/post/8iu7g5e3r6y.html 目录 引言1.初始化Hexo2.整合主题Fluid3.部署评论系统Waline4.采用Nginx部署 引言 Hexo是中国台湾开发者Charlie在2012年创建的一个开源项目,旨在提供一个简单、快速且易于扩展的静态博客生…...
doris:MySQL Dump
Doris 在 0.15 之后的版本已经支持通过 mysqldump 工具导出数据或者表结构 使用示例 导出 导出 test 数据库中的 table1 表:mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test --tables table1 导出 test 数据库中的 table1 表结构&am…...
DeepSeek-R1 云环境搭建部署流程
DeepSeek横空出世,在国际AI圈备受关注,作为个人开发者,AI的应用可以有效地提高个人开发效率。除此之外,DeepSeek的思考过程、思考能力是开放的,这对我们对结果调优有很好的帮助效果。 DeepSeek是一个基于人工智能技术…...
LabVIEW铅酸蓄电池测试系统
本文介绍了基于LabVIEW的通用飞机铅酸蓄电池测试系统的设计与实现。系统通过模块化设计,利用多点传感器采集与高效的数据处理技术,显著提高了蓄电池测试的准确性和效率。 项目背景 随着通用航空的快速发展,对飞机铅酸蓄电池的测试需求也…...
android studio无痛入门
在Android Studio中创建和管理项目主要涉及以下几个步骤: 1. 创建新项目 打开Android Studio,点击“Start a new Android Studio project”或者“File” > “New” > “New Project”。 选择一个模板,例如“Empty Activity”࿰…...
GNN多任务预测模型实现(二):将EXCEL数据转换为图数据
目录 一. 引言 二. 加载和检查数据 三. 提取特征和标签 四. 标准化特征 五. 构建节点索引 六. 构建边及其特征 七. 总结 八. 结语 一. 引言 在图神经网络(Graph Neural Networks, GNNs)的多任务学习场景中,数据预处理是至关重要的一…...
【机器学习】K-Nearest Neighbor KNN算法原理简介及要点
KNN算法用于分类 简介KNN分类算法的流程距离度量K值选择分类表决加权分类表决 简介 KNN的全称是K Nearest Neighbors. 这种算法可以被用来进行分类,原理是根据离特征点最近的K个点所属的类别进行分类。 KNN分类算法的流程 KNN算法的整体流程是我们需要将训练数据…...
ARM嵌入式学习--第十三天(I2C)
I2C --介绍 I2C(Inter-intergrated Circuit 集成电路)总线是Philips公司在八十年代初推出的一种串行、半双工的总线,主要用于近距离、低速的芯片之间的通信;I2C总线有俩根双向的信号线,一根数据线SDA用于收发数据&…...
error: externally-managed-environment
当你执行 pip3 install ipykernel 时遇到 error: externally-managed-environment 错误,这是因为从 Python 3.11 开始,为了避免破坏系统级 Python 环境,引入了外部管理环境(externally - managed environment)的概念&a…...
使用PyCharm进行Django项目开发环境搭建
如果在PyCharm中创建Django项目 1. 打开PyCharm,选择新建项目 2.左侧选择Django,并设置项目名称 3.查看项目解释器初始配置 4.新建应用程序 执行以下操作之一: 转到工具| 运行manage.py任务或按CtrlAltR 在打开的manage.pystartapp控制台…...
移动机器人规划控制入门与实践:基于navigation2 学习笔记(一)
课程实践: (1)手写A*代码并且调试,总结优缺点 (2)基于Gazebo仿真,完成给定机器人在给定地图中的导航调试 (3)使用Groot设计自己的导航行为树 掌握一门技术 规划控制概述 常见移动机器人...
TCP服务器与客户端搭建
一、思维导图 二、给代码添加链表 【server.c】 #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <fcntl.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.…...
flutter Selector 使用
在 Flutter 中,Selector 是 provider 包中的一个组件,用于在状态管理中高效地选择和监听特定部分的状态变化。Selector 可以帮助你避免不必要的重建,只在你关心的数据发生变化时才重建 widget。 基本用法 Selector 的基本用法如下ÿ…...
deepseek来讲lua
Lua 是一种轻量级、高效、可嵌入的脚本语言,广泛应用于游戏开发、嵌入式系统、Web 服务器等领域。以下是 Lua 的主要特点和一些基本概念: 1. 特点 轻量级:Lua 的核心非常小,适合嵌入到其他应用程序中。高效:Lua 的执…...
【大数据技术】本机DataGrip远程连接虚拟机MySQL/Hive
本机DataGrip远程连接虚拟机MySQL/Hive datagrip-2024.3.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本机的DataGrip连接虚拟机的MySQL数据库和Hive数据库,提高编程效率。 安装DataGrip 请按照以下步骤安装DataGrip软…...
【C++篇】C++11新特性总结1
目录 1,C11的发展历史 2,列表初始化 2.1C98传统的{} 2.2,C11中的{} 2.3,C11中的std::initializer_list 3,右值引用和移动语义 3.1,左值和右值 3.2,左值引用和右值引用 3.3,…...
redis之RDB持久化过程
redis的rdb持久化过程 流程图就想表达两点: 1.主进程会fork一个子进程,子进程共享主进程内存数据(fork其实是复制页表),子进程读取数据并写到新的rdb文件,最后替换旧的rdb文件。 2.在持久化过程中主进程接收到用户写操作&#x…...
操作系统—进程与线程
补充知识 PSW程序状态字寄存器PC程序计数器:存放下一条指令的地址IR指令寄存器:存放当前正在执行的指令通用寄存器:存放其他一些必要信息 进程 进程:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位…...
CV(11)-图像分割
前言 仅记录学习过程,有问题欢迎讨论 图像分割 语义分割不需要区分具体的个体,实例分割需要 反卷积/转置卷积: 它并不是正向卷积的完全逆过程。反卷积是一种特殊的正向卷积,先按照一定的比例通过补0 来扩大输入图像的尺寸&…...
