腾讯云分布式缓存数据库支持 Redis、Valkey、Memcached 等多种存储引擎。本文档定义缓存实例中 Key 与 Value 的设计原则,帮助您在开发过程中规范数据模型设计,提升缓存性能和可维护性。一、Key 设计原则Key 命名需具有可读性及可管理性,不建议使用含义不清的 Key 以及特别长的 Key 名。原则说明简洁性保证语义的前提下,可以适当缩短 Key 的长度。当 Key 较多时,Key 占用的内存空间也不容忽视。命名规则以英文字母开头,命名中只能出现大小写字母、数字、竖线、下划线、英文点号(.)和英文半角冒号(:)。语义分割不同业务逻辑含义使用英文半角冒号(:)分割,同一业务逻辑含义段的单词之间使用英文半角点号(.)分割,用来表示一个完整的语义。可读性Key 名称以 Key 所代表的 Value 类型结尾,以提高可读性。例如:user:basic.info:userid:string。长度限制Key 名称过大也会占用一定的内存空间,建议控制在128字节以内。禁止特殊字符禁止使用 \\、*、?、{}、[]、()、空格、单双引号和转义字符等,否则可能导致 Key 无法检索或检索失败。正确示例:示例说明cx:cxdb:user:000110011简洁、语义清晰,使用冒号分层。user:basic.info:userid:string同一语义段使用点号分割,以 Value 类型结尾。反面示例:示例问题cx:cxdb:cxdb_user_info:000110011表名中重复包含库名 "cxdb",冗余且增加 Key 长度。set user 000110011Key 中包含空格,属于禁止使用的特殊字符。二、Key 生命周期准则建议使用 expire 设置过期时间,控制 Key 的生命周期。# 写入 Key> set cx:cxdb:user:000110011 xiaoming# 设置 Key 一小时后过期> expire cx:cxdb:user:000110011 3600如果条件允许可以打散过期时间,防止集中过期。对于没有设置过期的数据,重点关注 idletime。在 idletime 非常大时进行清理。当一个 Key 有1个月以上未被访问过,则可以认定为冷数据,并进行清理。查看 Key 闲置时间示例:> object idletime cx:cxdb:user:000110011(integer) 150039 # 表示该 Key 有 150039 秒未被访问过说明:如果条件允许,建议为过期时间增加随机偏移量(例如基础 TTL ± 随机秒数),避免大量 Key 在同一时刻集中过期导致缓存雪崩。三、Value 设计原则3.1 拒绝大 Key大 Key 具体表现为缓存实例中的 Key 对应的 Value 很大,占用内存空间比较大,本质上是大 Value 问题。对于不同的数据结构类型,常见示例如下所示:数据结构类型大 Key 判定条件问题说明StringValue 值超过10MB。数据值太大Set成员数量超过10000个。成员数量多List成员数量超过10000个。成员数量多Hash成员数量超过1000个,且成员总 Value 值大小为1000MB。成员总的体积过大大 Key 很容易造成慢查询,阻塞其他的请求,同时也会对网卡造成负担。为防止产生大 Key,设计 Value 时建议参考如下准则:准则说明控制 Value 大小String 类型控制在10KB以内;Hash、List、Set、Zset 元素个数不要超过5000。避免直接删除大 Key若非必须,不要使用 del 删除大 Key。渐进式删除对于非字符串的大 Key,建议使用 hscan、sscan、zscan 渐进式删除。关注过期自动删除防止大 Key 过期时间自动删除问题。例如一个200万的 Zset 设置1小时过期,会触发 del 操作,造成阻塞。3.2 合理选择数据类型缓存实例提供了多种不同的数据结构类型,包括字符串、哈希表、列表、集合和有序集合等。选择合适的数据结构类型可以提升缓存性能和可靠性。数据结构类型适用场景说明字符串(String)简单的字符串数据,例如配置信息、计数器等如果需要存储二进制数据,可以使用二进制安全字符串类型哈希表(Hash)多个字段和值的数据,例如用户信息、商品信息等可以节省内存空间,方便进行批量操作列表(List)有序的元素集合,例如消息队列、任务列表等支持在两端进行插入和删除操作集合(Set)无序的元素集合,例如标签列表、好友列表等支持并集、交集、差集等操作有序集合(Sorted Set)有序的元素集合,例如排行榜、投票列表等按照分值排序,支持范围查询3.3 内存编码优化合理控制和使用数据结构内存编码优化配置。例如 ziplist 是一种特殊的数据结构,可以将小型列表、哈希表和有序集合存储在一个连续的内存块中,从而节省内存空间。场景建议数据量较小且需要频繁遍历适合使用 ziplist,内存利用率更高数据量较大且需要频繁插入、删除或查找不建议使用 ziplist,应考虑使用其他数据结构代替说明:ziplist 没有索引,查找、插入或删除操作需要进行线性扫描,数据量较大时可能导致性能下降。应根据具体数据量和访问模式决定是否启用。3.4 使用 Hash 代替多个 String如果一个 Key 有多个属性,可以考虑使用 Hash 类型来代替 String 类型。Hash 是一种键值对存储数据结构,可以用于存储多个字段和值。使用 HSET 命令将多个字段和值存储在一个哈希表中,然后使用 HGET 命令获取指定字段的值。如果使用 String 类型来存储多个属性,则需要使用特定的分隔符将不同的属性值拼接成一个字符串,这样会使得操作复杂,并且可能会浪费内存空间。反面示例: 使用多个 String 类型存储同一对象的属性,Key 数量膨胀且无法原子操作。set user:1:name tomset user:1:age 19set user:1:favor footballRunning EnvironmentOperating System: Ubuntu 24.04.3 LTS / x86_64

Runtime Version: GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)

正确示例: 使用 Hash 类型将同一对象的多个属性聚合为一个 Key,减少 Key 数量并支持原子操作。hmset user:1 name tom age 19 favor football