一、键值设计
1、key名设计
【基本原则】
key中添加前缀,以示区分,防止key冲突;
控制key的长度,减少无意义的内存浪费;
key中不要包含特殊字符(空格、引号、换行符等);
【各项目key命名规范】
1、 整体格式
整体分为4级:${team}+${project}+${func}+${key}。含义如下表所示:
等级 | 说明 | 必须 |
第一级 | 战队名($team),由公司统一定义,参见后面的列表。 | 是 |
第二级 | 项目名($project),由项目组自己申请,并提交公司备案。 | 是 |
第三级 | 功能名($func) | 是 |
第四级 | 具体业务关键字($key) | 是 |
2、 各战队(team)项目(project)英文名称对照表(若有新的,联系架构组添加):
战队 | 代号 | 工程代号 | RedisKey值前缀 | Master | PO |
---|---|---|---|---|---|
示例:会员注册信息key:z.i.reg.xxx
${team}=z, ${project}=i, ${func}=reg, ${key}=xxx
3、 命名规范
对于${team}、${project}、${func},原则上只能是英文小写,每个部分长度不超过3;
对于${key},要求不能使用特殊字符(空格、引号、换行符等),长度不超过18(身份证长度);
注意,在key中是允许使用业务唯一id的,例如 z.i.fr.m.{mid},mid就是message id。
每一级用英文分割符 "." "_" ":" 分割;
[例] 会员注册信息key,规范写法示例:z.i.reg.xxx
另外允许project有两级(可能是 project.sub-project 形式),允许func有两级(可能是 module.func 模式);
例如,项目fm有两个子项目manage和service,可以为fm.m和fm.s;
例如,friends模块,有messages和comments两个子功能,可以为fr.m和fr.c。
如果有特殊违例的情况,需单独评审说明。
2、value设计
1.【强制】:拒绝bigkey(防止网卡流量、慢查询)
string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5万。
反例:一个包含200万个元素的list。
2.【推荐】:控制key的生命周期,redis不是垃圾桶
建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime。
3.【推荐】:选择适合的数据类型
选择合适的存储方式和数据结构,注意节省内存和性能之间的平衡。
反例:
set user:1:name tom
set user:1:age 19
set user:1:favor football
正例:
hmset user:1 name tom age 19 favor football
二、Redis的使用
1、【推荐】
一般情况下,只使用Redis的简单缓存功能:
不得把Redis当做数据库使用,做长时间的持久化存储。
如果要用Redis实现一些高级功能或者存储数据量较大,务必联系架构组,需要通过技术评审。
2、【推荐】
避免多个应用使用同一个Redis实例,建议区分Redis集群,以便不互相干扰。
正例:不相干的业务拆分,公共数据做服务化。
3、【推荐】
使用带有连接池的客户端(例如JedisPool),可以有效控制连接,同时提高效率。
可参考网上“JedisPool资源池优化” 相关的文档。
4、【推荐】 O(N)命令关注N的数量
数据量大时,谨慎使用 hgetall、lrange、smembers、zrange、sinter ,但是需要明确复杂度。有遍历的需求可以使用 hscan、sscan、zscan 代替。
5、【推荐】:禁用命令
禁止线上使用keys、flushall、flushdb等命令。
6、【推荐】使用批量操作提高效率
原生命令:例如mget、mset。非原生命令:可以使用pipeline提高效率。
但要注意控制一次批量操作的元素个数(例如500以内,实际也和元素字节数有关)。
参见:
7、【建议】必要情况下使用monitor命令时,要注意不要长时间使用。
Monitor命令长期执行可能会导致占用大量内存,参见:Redis内存占用飙升
三、附录
参考文档:
http://carlosfu.iteye.com/blog/2254154