redis 规范

1. key设计
(1)【建议】: 可读性和可管理性
以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,如: 业务名:模块名:功能名:id
(2)【建议】:简洁性
保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,key的长度不超过100个字符,例如:
(3)【强制】:不要包含特殊字符
反例:包含空格、换行、单双引号以及其他转义字符
(4)【推荐】:控制key的生命周期
建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime。一般
建议设置过期时间是24小时,最长可设置过期时间10天,如有特殊要求,进行申请说明。
2. value设计
(1)【强制】:拒绝bigkey(防止网卡流量、慢查询)
string类型控制在100KB以内,hash、list、set、zset元素个数不要超过10000,size不超过1G。
反例:
一个包含200万个元素的list。
非字符串的bigkey,不要使用del删除,使用hscan、sscan、zscan方式渐进式删除,同时要注意防止bigkey过期
时间自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞,而且该操作不会不出现在慢
查询中(latency可查)),查找方法和删除方法
(2)【推荐】:选择适合的数据类型。
例如:实体类型(要合理控制和使用数据结构内存编码优化配置,例如ziplist,但也要注意节省内存和性能之间的平
衡)
反例:
正例:
iFinD:IStrategy:UserInfo:ifind_e001
iFinD:d41d8cd98f00b204e9800998ecf8427e/svc/thsft/Zend/application/modules/IStrategy/views/script
sroad‐show/create‐new.tpl
简化为
iFinD:IStrategy:road‐show:create‐new.tpl:d41d8cd98f00b204e9800998ecf8427e
set user:1:name tom
set user:1:age 19
set user:1:favor football
(3)【强制】:禁止大string
核心集群禁用1mb的string大key(虽然redis支持512MB大小的string),如果1mb的key每秒重复写入10次,就会导
致写入网络IO达10MB;
3. redis开发注意事项
(1)【推荐】:减少不必要的请求
redis默认对不存在的key值操作有返回值,所以,尽量减少使用exists或del请求。
反例:
某业务系统的使用redis,根据开发同学反馈好像系统的吞吐量不高,于是我们对该redis实例进行了请求采样
分析。采样100万次请求结果大概是这样的:该实例平均10554QPS,存在一次超过10000微秒的请求,平均
响应时间为56.25微秒(Median :56.25,75% :114.0,90%:206.0,99%:561.0),其中“EXISTS”占
37.34%请求。原来开发的同学在每次的请求之前都做了一次exists的请求,确认需要执行操作的key是否存
在,其实大可不必,因为redis的所有请求对于不存在的key都会有输出返回,所以干掉所有的exists请求以
后,在tps不变的情况下,该实例的有效用户请求能够提升:59.6%。
(2)【推荐】:注意请求的时间复杂度
redis是单线程作业,因此一个复杂度高的请求对于一个高并发低延迟的系统是致命的,它会大大的拉低系统的整
体吞吐,如果一定需要请把这些复杂度较高的请求(比如O(N))放在一个slave server。
反例:
将复杂度为O(log(N)+M)的ZREVRANGE操作转换为list的O(1)操作,单单这点优化qps从5000上升到6500,
约提升了30%。
(3)【建议】:冷热数据分离,不要将所有数据全部都放到同一个Redis中
冷热数据分离,不要将所有数据全部都放到Redis中。不同的业务数据要分开存储。
(4)【强制】:线上Redis禁止使用Keys正则匹配操作
Redis是单线程处理,在线上KEY数量较多时,操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞
线上其它命令的正常请求,而且在高QPS情况下会直接造成Redis服务崩溃!如果有类似需求,请使用scan命令代
替!
(5)【推荐】:谨慎全量操作Hash、Set等集合结构
在使用HASH结构存储对象属性时,开始只有有限的十几个field,往往使用HGETALL获取所有成员,效率也很高,
但是随着业务发展,会将field扩张到上百个甚至几百个,此时还使用HGETALL会出现效率急剧下降、网卡频繁打满
等问题【时间复杂度O(N)】,此时建议根据业务拆分为多个Hash结构;或者如果大部分都是获取所有属性的操作,可
以将所有属性序列化为一个STRING类型存储!同样在使用SMEMBERS操作SET结构类型时也是相同的情况!
hmset user:1 name tom age 19 favor football

你可能感兴趣的:(redis)