首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >[hash tag]为什么说redis的key名称中带上{},查询性能会提升

[hash tag]为什么说redis的key名称中带上{},查询性能会提升

原创
作者头像
保持热爱奔赴山海
修改2025-07-30 15:59:25
修改2025-07-30 15:59:25
3210
举报
文章被收录于专栏:数据库相关数据库相关

在 Redis 中,​Key 名称中包含 {}(大括号)[Redis 的 Hash Tag(哈希标签)机制]​​ 可以提升查询性能,主要是因为 ​Redis Cluster(集群模式)​​ 的 ​Key 分片(Hash Slot)机制​ 会优先使用 {} 内的内容来计算 Key 的哈希槽(Hash Slot),从而优化 Key 的分布和查询效率。

1. Redis Cluster 的 Hash Slot 机制

Redis Cluster 将所有的 Key 分布在 ​16384 个 Hash Slot(哈希槽)​​ 上,每个 Key 会被分配到一个固定的 Slot,然后由对应的 Redis 节点负责存储和查询。

Key 的 Hash Slot 计算方式

  • 默认情况下,Redis 会对整个 Key 进行 CRC16 计算,然后取模 16384 得到 Hash Slot:plaintext复制hash_slot = CRC16(key) % 16384
  • 如果 Key 包含 {},Redis 会 ​只计算 {} 内的内容​ 的 CRC16,然后取模 16384 得到 Hash Slot:plaintext复制hash_slot = CRC16(key_inside_braces) % 16384

2. 为什么 {} 能提升查询性能?​

​(1)减少跨节点查询(避免 Cross-Slot 查询)​

  • 在 Redis Cluster 中,​一个命令只能操作同一个 Hash Slot 的 Key,否则会报错
代码语言:txt
复制
CROSSSLOT Keys in request don't hash to the same slot
  • ​如果 Key 没有 {},整个 Key 的 CRC16 决定 Hash Slot,可能导致:
    • 相关 Key(如 user:1001user:1001:profile)被分配到不同的 Slot,导致无法用 MGETPipeline 批量查询。
  • 如果 Key 包含 {},可以 ​手动控制 Hash Slot,让相关 Key 落在同一个 Slot,从而支持批量操作:plaintext复制key1: {user:1001}:name key2: {user:1001}:profile
    • 这样 key1key2{user:1001} 部分相同,CRC16 计算相同,Hash Slot 相同,可以一起查询。

​(2)优化热点 Key 的分布

  • 如果某些 Key 访问非常频繁(热点 Key),可以通过 {} 让它们落在同一个 Slot,减少跨节点查询的开销。
  • 例如:plaintext复制hot_key1: {hot}:user:1001 hot_key2: {hot}:user:1001:profile
    • 这样 hot_key1hot_key2 会落在同一个 Slot,减少网络开销。

​(3)避免 Hash Tag 冲突(可选)​

  • 如果多个 Key 的 {} 内容不同,但 CRC16 计算后落在同一个 Slot,可能会导致 ​Hash 冲突​(虽然概率很低)。
  • 但这种情况极少发生,因为 CRC16 的分布比较均匀。

3. 实际案例

案例 1:用户数据存储

假设我们存储用户数据:

代码语言:javascript
复制
user:1001:name
user:1001:profile
user:1001:orders
  • ​如果没有 {}
    • user:1001:nameuser:1001:profile 可能落在不同的 Slot,无法用 MGET 批量查询。
  • ​如果使用 {}:plaintext复制{user:1001}:name {user:1001}:profile {user:1001}:orders
    • 这样所有 Key 的 {user:1001} 部分相同,Hash Slot 相同,可以一起查询:bash复制MGET {user:1001}:name {user:1001}:profile {user:1001}:orders

例如如下的例子:

代码语言:txt
复制
set {user:1001}:name zhangsan
set {user:1001}:profile '{"age":22,"sex":"M"}'

set user:1002:name zhangsan
set user:1002:profile '{"age":22,"sex":"M"}'

mget {user:1001}:name  {user:1001}:profile
mget user:1002:name user:1002:profile 

mget查询如下图:

案例 2:缓存 Key 设计

假设我们缓存商品数据:

代码语言:javascript
复制
product:1001:info
product:1001:price
product:1001:stock
  • 如果没有 {}
    • product:1001:infoproduct:1001:price 可能落在不同的 Slot,无法批量查询。
  • ​如果使用 {}​:plaintext复制{product:1001}:info {product:1001}:price {product:1001}:stock
    • 这样所有 Key 的 {product:1001} 部分相同,Hash Slot 相同,可以一起查询:bash复制MGET {product:1001}:info {product:1001}:price {product:1001}:stock

4. 注意事项

1 {} 内的内容越短越好

  • {} 内的内容会影响 Hash Slot 计算,如果内容太长,可能会增加 CRC16 计算的开销(但影响很小)。
  • 建议 {} 内只放关键标识,如 user:1001 或 product:1001,而不是整个 Key。

2 {} 不是必须的

  • 如果你的 Redis 是单机模式(非 Cluster),或者 Key 不需要批量操作,可以不用 {}。
  • 只有在 ​Redis Cluster​ 或需要 ​优化热点 Key​ 时才需要使用。

​3 {} 不能滥用

  • 如果所有 Key 都用相同的 {} 内容(如 {default}),会导致所有 Key 落在同一个 Slot(也就是造成某个shard热点问题),失去 Cluster 的分布式优势。

5. 总结

情况

是否使用 {}

Hash Slot 计算方式

是否支持批量查询

适用场景

​单机 Redis​

不需要

整个 Key 计算

支持

无 Cluster 环境

​Redis Cluster​

不使用

整个 Key 计算

可能不支持(跨 Slot)

Key 分布随机

​Redis Cluster​

使用 {}

只计算 {} 内内容

支持(同 Slot)

需要批量查询或优化热点 Key

结论​:

  • 在 Redis Cluster 中,Key 名称包含 {} 可以让相关 Key 落在同一个 Hash Slot,从而支持批量查询(如 MGETPipeline),提升查询性能。​
  • 适用于需要优化热点 Key 或批量操作的场景。​
  • 单机 Redis 不需要使用 {},因为没有 Cluster 的 Slot 限制。​

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ​1. Redis Cluster 的 Hash Slot 机制​
    • ​Key 的 Hash Slot 计算方式​
  • ​2. 为什么 {} 能提升查询性能?​​
    • ​​(1)减少跨节点查询(避免 Cross-Slot 查询)​​
    • ​​(2)优化热点 Key 的分布​
    • ​​(3)避免 Hash Tag 冲突(可选)​​
  • ​3. 实际案例​
    • ​案例 1:用户数据存储​
    • ​案例 2:缓存 Key 设计​
  • ​4. 注意事项
  • ​5. 总结​
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档