一、键值对使用规范
1):key的命令要具有可读性、可维护性。便于定位问题和寻找数据
2):value要避免出现bigkey,选择高效的序列化和压缩、使用对象共享池,选择高效恰当的数据类型
1、Key命名规范
① :【可读性和可管理性】规范的key命名,在遇到问题时能够方便定位。
Redis属于没有Schema的NoSQL数据库,所以需要通过key前缀来区分不同的业务数据,清晰明了。
把「业务模块名」作为前缀(好比数据库 Scheme),通过「冒号」分隔,再加上「具体业务名」。这样我们就可以通过 key 前缀来区分不同的业务数据,清晰明了。总结起来就是:「业务名:表名:id」
②:【简洁性】key长度控制在合理范围内
Key是字符串的情况下,底层的数据结构是SDS,SDS中会包含字符串长度、分配空间大小等元数据信息
保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视
③:不要包含特殊字符
反例:包含空格、换行、单双引号以及其他转义字符
2、Value设计
①:拒绝bigkey(防止网卡流量、慢查询)
string类型控制在1MB以内,hash、list、set、zset元素个数不要超过5000
反例:一个包含200万个元素的list
②:选择合适的数据存储服务(Redis不是万金油)
反例:使用Redis列表List做大吞吐消息队列,下游消费不及时会造成Redis内存容量打满
③:选择适合的数据类型
数据类型
|
存储的值
|
常见使用场景
|
常用存储模式
|
STRING(字符串)
|
可存储整数、浮点数和字符串,最大512M
|
计数器,实时指标,缓存串
|
GET/SET/INCRBY
|
HASH(散列/哈希表)
|
无序的键值对(最大2^32-1个字段)
|
“对象”结构存储
|
HSET/HGET/HLEN/HKEYS
|
LIST(列表)
|
字符串元素列表,存储与元素插入顺序一致(最大2^32-1个元素)
|
LIST(列表) 字符串元素列表,存储与元素插入顺序一致(最大2^32-1个元素) 队列,堆栈,日志消息队列,timeline
redis不建议做的的队列,以免数据倾斜和阻塞,大的队列建议使用talos
|
LPUSH/LPOP/LRANGE
|
SET(集合)
|
存储无序、唯一的字符串元素集合(2^32-1个元素)
|
元素记录不重复无序的场景(用户已安装的appid,参加的活动)
|
SADD/SMOVE/SCARD/SMEBMERS
|
SORTED SET(有序集合)
|
每个字符串成员附加1浮点数分值(score),元素排列顺序由其分值大小决定
|
排行榜(米币用户充值topN),实时动态
|
ZADD/ZRANGE/ZCARD
|
④:控制key的生命周期(redis不是垃圾桶)
缓存场景,建议Key都设置TTL值,使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期) 保证不使用的Key能被及时清理或淘汰,使内存复用
⑤:数据打散,避免节点倾斜
在集群模式下,热点Key和大容量Key尽量设计打散;避免集群QPS和容量不均衡,导致部分节点QPS过载和容量过大。缓存热点key一致性要求不高可以缓存在本地,降低Redis请求
二、命令使用规范
1、O(N)命令关注N的数量
redis 那么快,慢查询除了网络延迟,就属于这些批量操作函数。大多数线上问题都是由于这些函数引起;例如hgetall、lrange、smembers、zrange、sinter等并非不能使用,但是需要明确N的值。有遍历的需求可以使用hscan、sscan、zscan代替
2、禁用危险命令
禁止线上使用keys、flushall、flushdb等,生产环境以及通过redis的rename机制禁掉命令,请不要在生产环境尝试,或者使用scan的方式渐进式处理
3、Redis事务功能较弱,不建议使用
Redis的事务功能较弱(不支持回滚),而且集群版本要求一次事务操作的key必须在一个slot上
4、删除
非字符串的bigkey,不要使用del删除(4以上的版本可以使用unlink异步删除),使用hscan、sscan、zscan方式渐进式删除,同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞,而且该操作不会不出现在慢查询中
[注]redis 4.0 lazy-free特性已支持key的异步删除
三、客户端使用
1、避免多个应用使用一个Redis实例
不相干的业务拆分,公共数据做服务化
2、使用带有连接池的数据库,可以有效控制连接,同时提高效率
3、高并发下建议客户端添加熔断功能 (例如 netflix hystrix)
4、敏感数据设置密码
5、根据自身业务类型,选好最大内存淘汰策略,设置好过期时间
默认策略是volatile-lru,即超过最大内存后,在过期键中使用 lru算法进行key的剔除,保证不过期数据不被删除,但是可能会出现 OOM 问题
四、数据保存规范
五、运维规范
END.