Redis 开发规范手册

一、  数据库选型

【建议】首先判断业务类型是否必须使用Redis存储数据,能否使用传统关系性数据库解决。使用Redis提前做好容量规划,注意数据冷热分离,避免将全部数据加载到Redis中。例如:

l   根据业务类型,选择合适的最大内存及淘汰策略,设置好Key过期时间

 

二、  Key命名

Redis有两层(key-value)或三层(key-field-value)结构,通常良好的Key命名习惯会为日常的开发和运维工作带来极大的便利性。

2.1     可读性

【建议】可读性高的Key命名有助于排查线上问题、方便的进行批量处理。建议使用业务名称加冒号分割命名,"业务名/数据库名:表名:id"作为前缀,key的长度不超过100个字符。例如:

l   当前redis内存暴涨,通过高频key前缀可以轻易的区分出是哪个系统的哪个模块在频繁操作,快速定位问题。

l   当定位到线上问题时,可以通过模式匹配批量处理该类Key。

2.2     简洁性

【建议】因为Redis中存储的Key数量可能非常庞大,在保证可读性的前提下,可以适当缩短Key的长度,以减小内存开销。例如:

l   建议key命名在64字符以内,在越庞大的系统中效果越明显。

原Key:

userid:{uid}:friends:messagesid:{mid}

缩短后的Key,至少降低10字节的空间:

uid:{uid}:friends:mid:{mid}

2.3     规范性

【强制】Key命名需强制遵守以下规范,例如:

l   禁止包含特殊字符。例如:空格、换行、单双引号以及其他转义字符

l   满足业务需要的情况下,尽量合理设置Key过期时间,建议过期时间打散,防止集中过期,并且越短越好

原Key:

redis> SET "userid:1:name" "Tom"  EX 90

redis> SET "userid:2:name" "Jack"  EX 90

redis> SET "userid:3:name" "Bob"  EX 90

优化过期时间后的Key:

redis> SET "userid:1:name" "Tom"  PX 60100

redis> SET "userid:2:name" "Jack"  PX 60200

redis> SET "userid:3:name" "Bob"  PX 60300

 

三、  Value设计

如果说Key规范命名极大的提高了开发运维的便利性,那么Value设计规范更大的增加了Redis运行的高性能和可靠性

3.1     数据类型

【建议】Redis相比其它内存型数据库具有更加丰富的数据类型可供应用选择。例如:

l   Strings类型: 单个kv存储、适用于如简单计数等。

l   Hash类型: 多个相关属性放到一个Hash中、适用于如存储对象。

l   Set类型: 集合类型、适用于如归类对象等

l   Sorted Set类型: 有序集合类型、适用于如榜单排行

l   Lists类型: 队列类型、适用于如队列、粉丝/关注列表等

l   特殊的数据类型:Hyperloglog、Geo、Scripting,需要提前跟DBA沟通

3.2     Bigkey

【强制】禁止Redis中出现Bigkey,防止出现高并发下网络拥堵、阻塞超时发生切换、集群内存空间不均衡、过期删除、迁移困难及慢查询。例如:

l   string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000(实际需要观察元素的字节数),建议压缩后存储

l   非字符串的bigkey,不要使用del删除,使用hscan、sscan、zscan方式渐进式删除

l   注意bigkey过期时间,过期后会自动触发del造成阻塞,并且该del不会记录到慢查询

3.3     定长更新

【建议】因为Redis内存使用具有预分配和惰性删除的特性,因此Value内容的长度频繁变化极易导致Redis内存碎片的产生。内存碎片风险如下:

l   当内存碎片较多时,会导致取少量数据扫描大量内存块,严重拖慢Redis的运行

l   目前Redis内存碎片回收方式较困难,基本需要重启Redis实例才能释放碎片

 

四、  Redis安全

4.1   运行安全

【强制】防止Redis运行期间发生阻塞、崩溃、被入侵

l   Redis务必配置复杂度高的访问密码(requirepass、masterauth),64位以上,防止暴力破解

l   避免用root用户启动

l   禁止测试环境连接与生产环境混用

l   禁止压测生产环境

l   禁止存储图片、音频、视频、文件等大数据

l   禁止不同业务使用相同Redis实例

l   优先选择Redis 4.0.14版本,若对高版本功能有需要,也可选择Redis 5.0.5版本

l   Redis单实例物理内存占用尽量保持在10G,最大不要超过20G

4.2   使用安全

l   高风险命令

【强制】数据清除:flushall、flushdb建议在Redis中禁用

【建议】Server运行:shutdown、monitor、config、save、bgsave、bgrewriteaof建议在Redis中rename-command

【建议】易阻塞:关注时间复杂度O(N)的命令:keys、smembers、lrange、hgetall、sinter等,使用时明确N的值。有遍历的需求可以使用hscan、sscan、zscan代替并在客户端进行去重。此外,del bigkey、flushdb/flushall删除大量数据时,也会造成Redis短时间阻塞。Redis 4.0版本推出后台异步删除的方式(UNLINK、flushdb/flushall async)来避免该情况

l   特性功能

【建议】select:Redis实例虽然支持多个库,但因为Redis是单线程架构,同时多个业务使用多个库仍然会相互干扰

【建议】批量操作提高效率:Redis原生支持mget、mset、hmset等命令批量操作,非原生批量操作可以使用pipline提高效率,注意一次批量操作的元素个数不要太多,最好在100以内,以实际元素字节数大小为准

n   原生命令为原子操作,pipline可以打包多个命令但为非原子操作

n   pipline需要客户端于服务端同时支持

【建议】事务:Redis事务功能支持较弱,不建议过多使用

【建议】消息队列:Redis List常被用作消息队列服务。因为功能相对简单,不支持消息重传、持久化等功能,当消费者崩溃时可能导致数据丢失。因此对于要求消息可靠性高的场景,建议使用更加专业的MQ软件

【建议】Redis cluster限制:

n   只支持具有相同slot值的key执行批量操作

n   一次事务操作的Key必须在一个slot中,可以hash tag实现定向分片(当一个key包含 {} 的时候,就不对整个key做hash,而仅对{}包括的字符串做hash)。

n   key是数据分区的最小粒度,因此不能将一个大的键值对象,如hash,list等映射到不同的节点上

n   不支持多数据库,只能使用默认的0号库

n   不能使用级联复制

 

五、  集群架构

【强制】Redis高可用相关规范

l   禁止将线下节点复制到线上主库

l   主从集群必须配置哨兵高可用

l   线上业务禁止使用级联架构

l   Redis Cluster集群架构至少三个分片

l   主从节点版本必须保持一致

 

六、  客户端

【建议】Redis客户端相关规范

l   使用带有连接池的客户端控制连接,提高通信效率。常用客户端比如Jedis、lettuce、Redisson

l   对于特别重要的数据、连接相关的操作需要保证捕获异常,防止错误被淹没、数据操作状态不确定

l   高并发下建议客户端添加熔断功能

原文地址:https://www.cnblogs.com/l10n/p/13753398.html