# Redis使用规范
## Redis使用规范
> Redis功能强大,不但支持数据类型丰富,还支持分布式事务、数据分片、数据持久化等功能,是分布式系统中不可或缺的内存数据库服务。然而性能再好的服务器,也经不住疯狂的滥用。通过禁用部分高风险功能,并制定开发规范,业务更能够以简洁、通用的思想去考虑问题。
### 键值设计
1. `key`设计。**可读与管理性**:以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如`业务名:表名:id`。**简洁性**:保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视。不要包含特殊字符
* 正例:`Tceon-PERFOOT :username:exrick`
* 反例:包含空格、换行、单双引号以及其他转义字符
2. `value`设计。**拒绝BigKey**:Redis 是单线程服务,防止慢查询,`string`类型控制在`10KB`以内,`hash、list、set、zset`元素个数不要超过`5000个`。非字符串的BigKey,不要使用`del`删除,使用`hscan、sscan、zscan`方式渐进式删除。
* 反例:一个包含200万个元素的`list`。
3. 缓存设置失效时间。**作为缓存使用的 Key,必须要设置失效时间**。失效时间并不是越长越好,请根据业务性质进行设置。建议使用expire设置过期时间`(条件允许可以打散过期时间,防止集中过期)`
> Tceon-PERFOOT 框架中使用Spring提供的`@Cachable`注解已配置默认失效时间,详见配置文件
### 使用规范
1. 冷热数据区分。虽然Redis支持持久化,但将所有数据存储在Redis 中,成本非常昂贵。`建议将热点数据 (如QPS超过5k) 的数据加载到Redis中`。
2. 业务数据分离。`不要将不相关的数据业务都放到一个Redis中`,避免多个应用使用一个Redis实例。一方面避免业务相互影响,另一方面避免单实例膨胀,并能在故障时降低影响面,快速恢复。
3. 缓存不能有中间态。`缓存应该仅作缓存使用`,去掉后业务逻辑不应发生改变,不可切入到业务里。
4. 连接数限制。连接的频繁创建和销毁,会浪费大量的系统资源,极端情况会造成宿主机当机。请确保使用了正确的Redis客户端连接池配置。
### 操作限制
1. 严禁使用`keys`。`keys`命令效率极低,属于`O(N)`操作,会阻塞其他命令,在集群上会是灾难性的操作。`DBA`应该`rename`重命名此命令,从根源禁用,仅DBA可操作。
> Tceon-PERFOOT 框架`common`包中已提供基于`scan`操作封装的方法,详见`RedisTemplateHelper`
2. 严禁使用`flush`。`flush`命令会清空所有数据,属于高危操作。`DBA`应该`rename`重命名此命令,从根源禁用。
3. 严禁作为消息队列使用。Redis当作消息队列使用,会有容量、网络、效率、功能方面的多种问题。如需要消息队列,可使用`高吞吐的Kafka`或者`高可靠的RocketMQ`。
4. 严禁不设置范围的批量操作。
* 严禁对`zset`的不设范围操作。`ZRANGE、 ZRANGEBYSCORE`等多个操作`zset`的函数,请指定范围。如不确定长度,可使用`ZCARD`判断长度。
* 正例:`ZRANGE myzset 0 100`
* 严禁对大数据量的key使用`HGETALL`。`HGETALL`会取出相关hash的所有数据,如果数据条数过大,同样会引起阻塞。如不确定长度,可使用`HLEN`先判断长度。
* Redis集群的`MGET`操作,会到各分片取数据聚合,相比传统的 M/S架构,性能会下降很多,请提前压测和评估。
* 严禁使用`sunion, sinter, sdiff`等一些聚合操作。
5. 禁用`select`函数。使用`select`函数用来切换`database`,这是很容易发生问题的,集群模式也不支持多个`database`,且没有任何收益。
6. 禁用事务。Redis本身已经很快了,且Redis的事务功能较弱(不支持回滚),如无大的必要,建议捕获异常进行回滚,不要使用事务函数。
> 当然有特殊场景如秒杀,可利用Redis事物的批量顺序执行特性配合`watch`使用
7. 禁用`lua`脚本扩展。它就像是`SQL`的存储过程,会引入性能和一些难以维护的问题。
8. 禁止长时间`monitor`。`monitor`函数可以快速看到当前Redis正在执行的数据流,但是高峰期长时间阻塞在`monitor`命令上,会严重影响Redis的性能。使用一定要特别特别注意时间。
- 前言版本&说明
- 概念
- Tceon-PERFOOT 是什么?
- 系统架构
- 主要使用的开源组件
- 角色控制访问权限(RBAC)
- 用户手册
- 系统配置
- 工作流使用配置
- 定时任务调度
- 项目本地运行
- 后端运行
- 前端运行
- 项目结构说明
- 附:使用Oracle等数据库
- 模块化版本
- 后端开发指南
- 基本开发指南
- 前后端数据交互标准
- 工具类及数据权限
- 代码生成器
- 增删改查CRUD
- 日志类型注解扩展
- 逻辑删除
- 各验证码使用及配置
- 前端开发指南
- 基本开发指南
- 主题/Logo/首页等配置
- 路由菜单配置
- 多语言国际化配置
- 自定义图标icon
- 工具类及数据获取
- 完整版开发指南
- 前端Vue代码生成器
- Activiti工作流
- 单点登录配置
- MinIO对象存储服务搭建
- 第三方社交账号配置
- 短信开发/站内消息/邮件
- Vaptcha验证码
- 禁用词使用
- Monaco代码编辑器
- 开放平台及单点登录
- 开放平台使用指南
- Web接入开发流程
- 单点登录开发指南
- 微信小程序端开发指南
- 项目导入与开发必读
- 通用方法工具类说明
- Uniapp端开发指南
- APP后端开发指南
- Uniapp前端开发指南
- 开发新功能示例
- 后端开发新模块
- 前端开发新页面
- 测试
- SonarQube代码质量管理
- TestNG单元测试
- ExtentReports测试报告
- Selenuim自动化Web测试
- Appuim自动化App测试
- JMeter压测性能测试
- 部署
- Spring Boot配置
- 快速部署
- 后端部署
- 前端部署
- 前端部署优化
- Docker容器化部署
- 服务器配置
- DevOps环境搭建
- 组件安装列表
- 开发设计规范
- 分支管理
- 数据库设计规范
- Redis使用规范
- Java基础开发规范
- Rest API规范
- 项目结构规范
- 前端开发规范
- 前端设计规范
- 项目搭建分享
- 后端相关
- SpringBoot 2.x区别总结
- Spring Security整合JWT
- Spring Security动态权限管理
- Spring Boot 2.x整合Quartz
- Spring Boot 2.x整合Websocket
- Spring Boot 2.x整合Activiti工作流以及模型设计器
- Spring Boot + Security全局跨域配置
- 前端相关
- axios请求封装 统一异常处理
- 动态路由菜单加载
- 多维度控制权限至按钮显示
- 发送消息图标红点实时显示
- 动态组件单页操作
- 常见问题