跳转到内容

Redis 中 Key 的层级格式与命名规范


Redis 的 Key 层级格式是一种人工约定的命名规范,并非 Redis 内置的技术特性。通过 : 等特殊字符分割不同层级,帮助开发者清晰组织和管理 Key。

层级格式示意:
user : 1001 : profile
│ │ │
业务模块 对象ID 子资源

命名公式: 项目名:业务模块:对象类型:ID:子资源

Terminal window
# 用户系统
user:1001:profile # 用户 1001 的基本信息
user:1001:orders # 用户 1001 的订单列表
user:1001:token # 用户 1001 的登录 Token
# 商品系统
product:789:info # 商品 789 的元数据
product:789:stock # 商品 789 的库存
# 多项目隔离(微服务场景)
mall:user:1001:profile # mall 项目的用户信息
pay:user:1001:balance # pay 项目的用户余额(前缀隔离,互不干扰)

价值说明
可读性一眼看出 Key 的归属业务、对象类型和用途
防冲突不同业务/服务使用不同前缀,天然隔离命名空间
便于管理配合 SCAN MATCH 可批量查找/清理某类 Key
工具友好Redis 管理工具(如 RedisInsight)会按 : 自动分组展示,形成树形结构

分隔符推荐度说明
:✅ 强烈推荐社区惯例,管理工具原生支持分组
_⚠️ 可用: 混用时容易混乱
/❌ 不推荐与路径语义冲突,易混淆
.❌ 不推荐与域名/属性访问语义冲突
建议说明
控制在 44 字节以内Redis 对 ≤44 字节的 String key 使用 embstr 编码,内存更紧凑
避免超过 128 字节过长的 Key 占用内存多,且每次操作都要传输完整 Key
缩写模块名usr 代替 userprd 代替 product(大规模 Key 时节省内存显著)
避免动态时间戳拼接log:20260311:09:30:xx 这类 Key 难以管理,改用 ZSet score 存时间
Terminal window
# ❌ 无前缀,无法区分业务归属
SET name "Alice"
SET token "abc123"
# ❌ 过深层级,可读性差
SET user:1001:order:2024:03:detail:shipping:address "..."
# ❌ 大小写混用,容易拼错
SET User:1001:Profile "..."
SET user:1001:profile "..." # 与上面是两个不同 Key!
# ✅ 规范命名
SET user:1001:profile "..."
SET order:2024031001:detail "..."

对同一实体的多个属性,应优先用 Hash 而非多个层级 Key:

Terminal window
# ❌ 劣质方案:每个字段独立一个 Key
SET user:1001:name "Alice"
SET user:1001:age "25"
SET user:1001:email "alice@example.com"
# 问题:3 个 Key,3 次网络请求,内存开销大
# ✅ 优质方案:Hash 聚合同一对象的字段
HSET user:1001 name "Alice" age "25" email "alice@example.com"
# 优点:1 个 Key,1 次 HGETALL,内存更紧凑

手动拼接 Key 容易出错,推荐封装常量或工具类统一管理:

public interface RedisKeys {
// 用户模块
String USER_PROFILE = "user:%d:profile"; // %d = userId
String USER_TOKEN = "user:%d:token";
String USER_CART = "user:%d:cart";
// 商品模块
String PRODUCT_INFO = "product:%d:info"; // %d = productId
String PRODUCT_STOCK = "product:%d:stock";
// 验证码
String VERIFY_CODE = "verify:code:%s"; // %s = phone
static String userProfile(long userId) {
return String.format(USER_PROFILE, userId);
}
static String userToken(long userId) {
return String.format(USER_TOKEN, userId);
}
static String productInfo(long productId) {
return String.format(PRODUCT_INFO, productId);
}
static String verifyCode(String phone) {
return String.format(VERIFY_CODE, phone);
}
}
// 使用:清晰、无拼写错误
String key = RedisKeys.userProfile(1001L); // → "user:1001:profile"
redisTemplate.opsForValue().set(key, json, 1, TimeUnit.HOURS);
String codeKey = RedisKeys.verifyCode("13800138000"); // → "verify:code:13800138000"

5.2. Redisson Namespace(自动添加前缀)

Section titled “5.2. Redisson Namespace(自动添加前缀)”
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setPassword("123456");
// 全局 Key 前缀:所有操作的 Key 自动加上 "mall:" 前缀
config.setNamespacePrefix("mall:");
return Redisson.create(config);
}
// 业务代码中写 "user:1001",实际存储的 Key 是 "mall:user:1001"

Terminal window
# 分批次扫描(生产安全,不阻塞)
SCAN 0 MATCH user:*:token COUNT 100
# 对应 SpringBoot
Set<String> keys = new HashSet<>();
ScanOptions options = ScanOptions.scanOptions()
.match("user:*:token")
.count(100)
.build();
try (Cursor<String> cursor = redisTemplate.scan(options)) {
cursor.forEachRemaining(keys::add);
}

✅ 推荐写法:
{项目}:{模块}:{id}:{子资源}
全小写,: 分隔,层级 2~4 级
示例:
user:1001:profile
order:20260310001:status
verify:code:13800138000
mall:product:789:stock
❌ 避免写法:
无前缀:name / token / data
大小写混用:User:1001 / USER_TOKEN
过深层级:a:b:c:d:e:f:g
含时间戳的动态深层级:log:2026:03:11:09:30:detail