之前那样,如果要避免bigkey甚至其他的一些key冲突,我们其实需要对存值的时候的key,做好规范,因为在一个庞大的系统中,我们会有无数的key存在redis中,如果不做好规范管理,那么不仅会冲突,甚至会带来一些不可预料的生产风险。
Key设计规范
- 做好可读性:
- 比如:
bonus:company:1001
,这是某个企业的绩效奖金内容,我们通过业务名:实体名(数据名):实体ID
就可以构筑该redis的内容,那么这是从大到小的一个顺序,如此可以做好区分。而且他可读性也很高,让人一目了然。 - 此外也能避免key的冲突,因为开发一个项目,不同项目组可能都会需要使用到某个数据,如果不做好规约,那么可能key就冲突了,各自开发没关系,但是上线了就不好说了,一定会出现相互覆盖的问题。所以不同项目组可以再加一个团队名的前缀,也是可以的。
- 便于更直观和可管理,在所见即所得工具中可以一目了然。
- 比如:
- 避免key过长:
- 比如
company:hrUser:information
可以简写为:comp:hr:info
,如此也能降低key的存储空间,不要小看这个规范,如果有1亿个key的话,可以节省相当多的内存开支,内存开支就是钱啊,如果做的好,你是不是可以跟领导汇报就有的说了呀,/斜眼笑
- 比如
- 不要包含特殊字符:
- 我们就是用普通的英文+数字的组合即可,空格啊下划线啊等等这种符号不要用,没必要,哪怕可以使用,他也会增加计算损耗的。
- 合理拆分
- 一个对象的存储,不要把所有属性字段都存,如果必须使用,则拆为多个组合对象,比如每30个字段作为一个对象存储,如果业务层需求,获得后合并即可,这才是比较好的方式,一定要降低bigkey的出现风险。
对象存储规范
- Entity对象:String
- 可以直接保存为字符串,使用起来比较方便,使用场景全面
- 序列化和反序列化需要额外的损耗开销,另外对象中的属性是无法直接修改,需要拿出来在业务层修改后,再次存储redis中。假如100多个字段是无法进行拆开的,进行局部修改的。
- 使用场景:用户信息,企业信息,产品信息
- Entity对象:Hash
- 作为一个hash对象保存到redis中,与javabean对象的匹配度是最高的,也可以局部进行某一个属性的修改,不需要拿到业务层进行转换,直接在redis中进行计算,处理
- 拿出来转换为一个对象也需要在业务层做额外处理
- 使用场景:用户信息,企业信息,产品信息
- Entity对象:属性字段打散存储
- 这个时候不用把整个对象存在redis中,只需要每个字段属性单独存一下,比如:company:1001:name,company:1001:regdate 等,拿出来拼接会比较繁琐,这样也可以,如此就没有bigkey的风险了。
- 只不过这么做,占用的内存会更多,当然看企业如何决策,空间换低风险以及高性能,都可以。
推荐string+hash的方法
- List:String
- 适合保存一些小list,长度不高的,修改频率也不高的集合,如果是做分页那种的查询是不适合的
- 比较节省空间,同对象string一样无法直接修改某个集合中的数据,需要在业务层取出后修改再次存入
- 使用场景:短list集合,数据字典列表,微博排名,博客收藏排名,用户点赞排名,直播刷礼物排名等。
- List:list/set
- 可以使用它的内置api,比如交集差集并集等。也可以对内部的某个数据做出修改。
- 缺点:频繁去使用,list会越来越多,比较容易出现bigkey的情况