Key 与 Value 设计原则
最近更新时间: 2024-10-17 17:10:00
Key设计原则
设计合理的 Key,有助于保证数据库的性能。
Key 命名原则
Redis Key命名需具有可读性及可管理性,不建议使用含义不清的Key以及特别长的Key名。
简洁性:保证语义的前提下,可以适当缩短key的长度,当key较多时,key占用的内存空间也不容忽视,例如:cx:cxdb:cxdb_user_info:000110011可简化为cx:cxdb:user:000110011
命名规则:以英文字母开头,命名中只能出现大小写字母、数字、竖线、下划线、英文点号(.)和英文半角冒号(:)。
按照语义分割:不同业务逻辑含义使用英文半角冒号(:)分割,同一业务逻辑含义段的单词之间使用英文半角点号 (.)分割,用来表示一个完整的语义。
可读性:key名称以key所代表的value类型结尾,以提高可读性。例如:user:basic.info:userid:string。
不使用过大的key名称:key名称过大也会占用一定的内存空间。
禁止包含特殊字符:例如:\ 、*、 ?、 {}、 []、 ()、 空格、单双引号和转义字符等,如果key中存在特殊字符,可能会导致key无法检索或检索失败。
Key生命周期准则
建议使用 expire 设置过期时间,控制 Key 的生命周期。例如:
> set cx:cxdb:user:000110011 xiaoming
> expire cx:cxdb:user:000110011 3600 # 设置 Key 一小时后过期
如果条件允许可以打散过期时间,防止集中过期。
对于没有设置过期的数据,重点关注 idletime。idletime非常大时进行清理。例如,执行
> object idletime cx:cxdb:user:000110011
回显信息如下:
:(integer) 150039 # 这里表示key有150039秒未被访问过
当一个key有1个月以上未被访问过,则可以认定为冷数据,并进行清理。
Value 设计原则
拒绝 Big Key
大 Key 具体表现为 Redis 中的 Key 对应的 Value 很大,占用 Redis 空间比较大,本质上是大 Value 问题。对于 Redis 中不同的数据结构类型,常见示例如下所示。
对于 String 类型的 Value 值,值超过 10MB(数据值太大)。
对于 Set 类型的 Value 值,含有的成员数量为 10000 个(成员数量多)。
对于 List 类型的 Value 值,含有的成员数量为 10000 个(成员数量多)。
对于 Hash 格式的 Value 值,含有的成员数量 1000 个,但所有成员变量的总 Value 值大小为 1000MB(成员总的体积过大)。
Big key很容易造成慢查询,阻塞其他的请求。同时,也会对网卡造成负担。为防止产生大 Key,设计 Value 时,建议参考如下建议。
建议 String 类型控制在10KB以内;hash、list、set、zset元素个数不要超过5000。
若非必须,不要使用 del 删除大 Key。
对于非字符串的大 Key,建议使用hscan、sscan、zscan渐进式删除。
防止大 Key过期时间自动删除问题。
例如一个200万的zset设置1小时过期,会触发 del 操作,造成阻塞。
合理选择数据类型
Redis提供了多种不同的数据库类型,包括字符串、哈希表、列表、集合和有序集合等。选择合适的数据库类型可以提高Redis的性能和可靠性。
字符串类型:适用于存储简单的字符串数据,例如配置信息、计数器等。如果需要存储二进制数据,可以使用Redis的二进制安全字符串类型。
哈希表类型:适用于存储多个字段和值的数据,例如用户信息、商品信息等。哈希表可以节省内存空间,并且可以方便地进行批量操作。
列表类型:适用于存储有序的元素集合,例如消息队列、任务列表等。列表可以在两端进行插入和删除操作,并且可以使用Redis提供的多种操作命令来操作列表。
集合类型:适用于存储无序的元素集合,例如标签列表、好友列表等。集合可以进行并集、交集、差集等操作,并且可以使用Redis提供的多种操作命令来操作集合。
有序集合类型:适用于存储有序的元素集合,例如排行榜、投票列表等。有序集合可以按照分值进行排序,并且可以使用Redis提供的多种操作命令来操作有序集合。
合理控制和使用数据结构内存编码优化配置,例如ziplist是一种特殊的数据结构,它可以将小型列表、哈希表和有序集合存储在一个连续的内存块中,从而节省了内存空间。但是,由于ziplist没有索引,因此在对ziplist进行查找、插入或删除操作时,需要进行线性扫描,这可能会导致性能下降。在实际应用中,应该根据具体情况来决定是否使用ziplist。如果数据量较小且需要频繁进行遍历操作,那么使用ziplist可能是一个不错的选择。但是,如果数据量较大且需要频繁进行插入、删除或查找操作,那么使用ziplist可能会影响性能,应该考虑使用其他数据结构来代替。
此外,如果一个Key有多个属性,可以考虑使用HashMap类型来代替String类型。HashMap是Redis中的一种键值对存储数据结构,可以用于存储多个字段和值。在Redis中,可以使用HSET命令将多个字段和值存储在一个哈希表中,然后使用HGET命令获取指定字段的值。如果使用String类型来存储多个属性,则需要使用特定的分隔符将不同的属性值拼接成一个字符串,这样会使得操作复杂,并且可能会浪费内存空间。
反面示例
set user:1:name tom
set user:1:age 19
set user:1:favor football
正面示例
hmset user:1 name tom age 19 favor football