Redis规范
本文主要介绍在使用 Redis 时的开发规范。
Redis规范。持续补充...
- 键值设计
- 命令使用
- 标品里面集成使用
- 最佳实践
通过本文的介绍可以减少使用 Redis 过程带来的问题。
键值设计
- key名设计
以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id
ugc:video:1
保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,例如:
user:{uid}:friends:messages:{mid} 简化为u:{uid}:fr:m:{mid}
反例:包含空格、换行、单双引号以及其他转义字符
- value设计
- String:大小控制在 10KB 以下
- List/Hash/Set/ZSet:元素数量控制在 1 万以下
Redis 提供了丰富的数据类型,这些数据类型在实现上,也对内存使用做了优化。具体来说就是,一种数据类型对应多种数据结构来实现:
例如,String、Set 在存储 int 数据时,会采用整数编码存储。Hash、ZSet 在元素数量比较少时(可配置),会采用压缩列表(ziplist)存储,在存储比较多的数据时,才会转换为哈希表和跳表。
作者这么设计的原因,就是为了进一步节约内存资源。
那么你在存储数据时,就可以利用这些特性来优化 Redis 的内存。这里我给你的建议如下:
- String、Set:尽可能存储 int 类型数据
- Hash、ZSet:存储的元素数量控制在转换阈值之下,以压缩列表存储,节约内存
建议都设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime。
命令使用
- O(N)命令关注N的数量
例如 hgetall、lrange、smembers、zrange、sinter 等并非不能使用,但是需要明确N的值。有遍历的需求可以使用 hscan、sscan、zscan 代替。
- 禁用命令
禁止线上使用keys、flushall、flushdb等,通过 Redis 的rename机制禁掉命令,或者使用scan
的方式渐进式处理。
- 合理使用 select
Redis 的多数据库较弱,使用数字进行区分,很多客户端支持较差,同时多业务用多数据库实际还是单线程处理,会有干扰。
- 使用批量操作提高效率
- 原生命令:例如 mget、mset。(原生是原子操作)
- 非原生命令:可以使用 pipeline 提高效率。(非原子操作)
但要注意控制一次批量操作的元素个数(例如500以内,实际也和元素字节数有关)。
- 不建议过多使用 Redis 事务功能
Redis 的事务功能较弱(不支持回滚),而且集群版本(自研和官方)要求一次事务操作的 key 必须在一个 slot 上(可以使用 hashtag 功能解决)
Redis 集群版本在使用 Lua 上有特殊要求
- 所有 key 都应该由 KEYS 数组来传递
- 所有 key 必须在1个 slot 上,否则直接返回 error, "-ERR eval/evalsha command keys must in same slot"
monitor 命令
必要情况下使用 monitor 命令时,要注意不要长时间使用。
标品里面集成使用
最佳实践
为保障Redis
实例稳定、高效率地运行,部分命令需要被禁用。在业务场景中,无限制地允许命令使用可能带来诸多问题。一些命令会直接清空大量甚至全部数据。
禁用 keys,flushdb,flushall
- 阿里云
控制台上找到#no_loose_disabled-commands
参数,通过小写字母方式填入要禁用的命令。多个按英文逗号分隔。例如 keys,flushdb,flushall。
- 腾讯云
控制台找到disable-command-list
参数,进行勾选即可。