3、缓存索引基础:什么是缓存索引?索引在Redis中的存储模型与设计原则。

3.1 缓存索引的本质定义

在Redis缓存场景中,缓存索引并非传统数据库的B+Tree索引,而是一种键值映射结构——通过精心设计的Key模式,将业务查询维度快速定位到对应的Value存储位置。其核心价值在于:用O(1)的哈希查找替代全量扫描。

缓存索引 ≠ 数据库索引
数据库索引:维护数据物理顺序,支持范围扫描、回表查询。
缓存索引:基于Key的精确匹配,本质是哈希表查找,不支持范围扫描(除非使用Sorted Set)。

3.2 Redis索引的存储模型

Redis底层使用全局哈希表(dict)存储所有键值对。每个Key通过MurmurHash2算法计算哈希值,映射到哈希桶数组的某个槽位。当发生哈希冲突时,采用链地址法解决。

Redis 全局哈希表存储模型 桶 0 (dictEntry) 桶 1 (dictEntry) 桶 2 (dictEntry) 桶 3 (dictEntry) 桶 4 (dictEntry) 桶 5 (dictEntry) 桶 N (dictEntry) key:user:1001 key:user:1002 key:order:5001 key:session:abc 哈希冲突链 多个Key映射到 同一桶时形成链表 O(1) 查找 直接定位桶位置 链表长度影响性能

3.3 缓存索引的三种核心设计模式

设计模式 Key结构示例 适用场景 时间复杂度
直接键值索引 user:{id}:profile 主键查询、单条记录缓存 O(1)
复合字段索引 user:email:{email} 唯一索引字段查询(如邮箱、手机号) O(1)
辅助集合索引 user:city:{cityId}:ids (Set) 非唯一字段、多对多关系、标签查询 O(N) 遍历集合
设计原则:直接键值索引和复合字段索引应作为首选,辅助集合索引仅在需要按非唯一字段批量查询时使用,且需控制集合大小(建议不超过 5000 个元素)。

3.4 索引设计五大原则

  1. 唯一性优先:能用唯一字段(ID、邮箱)构建Key,绝不使用非唯一字段。
  2. 前缀命名空间:使用 业务域:实体:字段:值 的层级结构,避免Key冲突。
  3. 长度控制:Key总长度建议不超过 128 字节,过长会浪费内存并降低哈希计算效率。
  4. 避免热点桶:使用随机后缀或哈希后缀分散Key,防止大量Key映射到同一哈希桶。
  5. TTL与淘汰策略:所有缓存索引必须设置过期时间,配合LRU/LFU淘汰策略。

3.5 索引设计反模式与避坑

反模式 错误示例 后果 正确做法
Key过长 user_profile_info_by_user_id_1001 内存浪费、哈希计算慢 user:1001:profile
无命名空间 1001、abc123 Key冲突、难以管理 user:1001、session:abc123
大集合无分片 user:all:ids (Set存100万ID) 单Key内存过大、读写阻塞 按哈希分片 user:ids:0 ~ user:ids:15
忽略过期时间 cache:data:1 无TTL 内存持续增长、无法淘汰 设置 EXPIRE cache:data:1 3600

3.6 复合索引与辅助索引的协同模型

在实际业务中,单一索引往往无法满足所有查询维度。下图展示了主索引 + 辅助索引的协同工作模式:

复合索引与辅助索引协同模型 按邮箱查询用户 email:alice@example.com 复合字段索引 user:email:alice@example.com 主数据 user:1001:profile 按城市查询用户列表 city:beijing 辅助集合索引 user:city:beijing:ids Set 集合 user:1001 user:1005 user:1020 协同查询流程 复合索引:直接返回主数据Key → 一次查询完成 辅助索引:先查集合获取所有ID → 再逐个查询主数据(N+1问题需注意)

3.7 索引内存开销估算

每个Key在Redis中都有固定内存开销,设计索引时必须量化评估:

组件 内存开销 说明
dictEntry 32 字节 每个Key/Value对的基础结构
Key字符串 Key长度 + 8 字节 Redis SDS 结构额外开销
Value指针 8 字节 指向实际数据对象的引用
哈希桶数组 8 字节 × 桶数量 初始 1024 个桶,动态扩容
实战警示:一个长度为 32 字节的Key,实际占用内存约为 32 + 8 + 32 + 8 = 80 字节。1000 万个索引Key仅基础开销就达 800 MB,还不包含Value本身。设计索引时必须压缩Key长度,优先使用数字ID而非字符串。

3.8 索引设计决策矩阵

业务查询模式 推荐索引类型 数据结构 示例
通过主键查询单条记录 直接键值索引 String / Hash user:1001 → Hash
通过唯一业务键查询 复合字段索引 String user:email:alice@example.com → user:1001
按分类/标签查询ID列表 辅助集合索引 Set article:tag:redis:ids → Set of article IDs
按时间范围查询 有序集合索引 Sorted Set order:create:202401 → score=timestamp
多字段组合查询 复合Key + 辅助索引 String + Set order:status:paid:city:beijing:ids
核心结论:缓存索引设计的本质是用空间换时间——通过冗余存储查询维度到Key中,换取O(1)的查询性能。但必须严格控制索引数量,每个额外的索引都意味着写入时的双倍开销和内存的线性增长。建议每个实体不超过 3 个辅助索引。